3.2 段设定伪指令ASSUME、如何装入四个寄存器

3.2 段设定伪指令ASSUME

作用

  • 告诉汇编程序,在处理源程序时,定义的段与哪个段寄存器关联
  • ASSUME并不设置各个段寄存器的具体内容段寄存器的值是在程序运行时设定的。
  • 汇编时,只是关联,未赋值。

使用

  • 在一个代码段中可以有几条ASSUME伪指令,对于前面的设置,可以用ASSUME改变原来的设置。

  • 一条ASSUME语句不一定设置全部段寄存器,可以选择其中一个或几个段寄存器。

  • 可以使用关键字NOTHING将前面的设置删除。

    • 例如:

    • ASSUME ES:NOTHING 	;删除前面对ES与某个定义段的关联
      ASSUME NOTHING		;删除全部4个段寄存器的设置
      

格式

  • ASSUME 段寄存器名:段名,段寄存器名:段名,..........
    • 其中,段寄存器名为CS, DS,ES和SS四个之一
    • 段名是用SEGMENT╱ENDS伪指令定义的段名

DATA1 SEGMENT
	VAR1 DB 12H
DATA1 ENDS
DATA2 SEGMENT
	VAR2DB 34H
DATA2 ENDS
CODE SEGMENT
	VAR3 DB56H
	ASSUME CS:CODE,DS:DATA1,ES:DATA2	;这里ASSUME来关联
START:
	.....
	INC VAR1	;该指令汇编时,VAR1使用的是DS
	INC VAR2	;该指令被汇编时,VAR2使用的是ES,即指令编码中有段前缀ES
	INC VAR3	;该指令汇编时,VAR3使用的是CS,即指令编码中有段前缀CS
	......
CODE ENDS
	END START

四个段寄存器的装入

  • 要让一个段寄存器真正地指向某个逻辑段,就需要将段基值装入到该段寄存器。
  • 段寄存器的装入需要用程序的方法来实现。四个段寄存器的装入方法略有不同

1.DS和ES的装入

  • 在程序中,使用数据传送语句来实现对DS和ES的装入。
DATA1 SEGMENT
	DBYTE1 DB 12H
DATA1 ENDS
DATA2 SEGMENT
	DBYTE2 DB 14H DUP(?)
DATA2 ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA1	;关联。
START: 	MOV AX,DATA1	;数据段DATA1放到寄存器AX
        MOV DS,AX		;数据段从AX放到DS
        MOV AX,DATA2	;数据段DATA2放到寄存器AX,但是前面并未关联DATA2
        MOV ES,AX		;数据段从AX放到ES
        MOV AL,DBYTE1	;数据从DBYTE1放到AL
        MOV DBYTE2[2],AL	;该指令在汇编时出错,因为在ASSUME指令中未指定ES与DATA2关联
		……………
CODE ENDS

  • 在汇编语言程序中,引用段名就是以立即数形式获取该逻辑段的段基址
  • 而在MOV指令中,立即数不能直传给段寄存器,所以给段寄存器的赋值必须经过一个通用的寄存器中转再送入DS/ES

3.2 段设定伪指令ASSUME、如何装入四个寄存器

改正方法:

1、可以在变量DBYTE2前加一个段前缀说明即可。即:

MOV ES:DBYTE2[2],AL

2、,最好的办法是在ASUMME语句中,将ES与DATA2关联。

2.SS的装入:

有两种方法

  • 1、(常用)段定义伪指令时,使用STACK参数并在段寻址伪指令ASSUME语句中,把该段与SS段寄存器关联
STACK1 SEGMENT PARA STACK	;这里是使用了STACK参数
	DB 40H DUP(?)
STACK1 ENDS
	…………
CODE SEGMENT
	ASSUME CS:CODE,SS:STACK1 ;这里是寄存器与段关联了
	…………					;SS将被自动装入STACK1段的段基值,堆栈指针SP也将指向堆栈底部+2的存储单元。这里(SP)=40H。
  • 2、在段定义伪指令时,未使用STACK参数,或者是在程序中要调换到另一个堆栈,使用类似于DS和ES的装入方法。
DATA_STACK SEGMENT
	DB 40H DUP(?)
	TOP LABEL WORD ;TOP变量的偏移量为40H,即栈底+2,这里是WORD,因为SP是按字操作的
DATA_STACK ENDS
	......
CODE SEGMENT
	......
	MOV AX,DATA_STACK
	MOV SS,AX
	MOV SP,OFFSET TOP
	......
	

3.2 段设定伪指令ASSUME、如何装入四个寄存器

3.CS的装入:

如何装入

  • CPU在执行指令之前根据CS和IP的内容来从内存中提取指令,即必须在程序执行之前装入CS和IP的值
  • 因此, CS和IP的初始值就不能用可执行语句来装入

格式

END 起始地址(段定义结束用:ENDS)	;起始地址:可以是一个标号或表达式
  • END伪指令用来指示源程序结束和指定程序运行时的起始地址
  • 当程序被装入内存时,系统软件根据起始地址段基值偏移量分别被装入CS和IP中。
CODE SEGMENT
	ASSUME CS:CODE.....
START: .....	;这里的起始地址就是标号START
CODE ENDS
	END START

装入CS和IP一般有下面两种情况。

1、由系统软件按照结束伪指令指定的地址装入初始的CS和IP,任何一个源程序都必须以END伪指令来结束。

2、在程序运行期间,当执行某些指令时,CPU自动修改CS和IP,使它们指向新的代码段,程序为非顺序执行中的某些类型〈不包括条件转移,循环等,它们是段内转移)。

例如:

  • 执行段间过程调用CALL和段间返回指令RET;
  • 执行段间无条件转移指令JMP;(段间转移)
  • 响应中断及中断返回指令;
  • 执行硬件复位操作。
上一篇:Elasticsearch配置讲解


下一篇:Docker部署单机版Elasticsearch