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。
改正方法:
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.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;(段间转移)
- 响应中断及中断返回指令;
- 执行硬件复位操作。