相对基址加变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器之一的内容与变址寄存器之一的内容与指令中给定的8位或16位位移量相加得到。也即:
在一般情况(即不使用段超越前缀指令明确指定段寄存器)下,如果BP之内容作为有效地址的一部分,则以SS段寄存器之内容为段值,否则以DS段寄存器之内为段值。
在指令中给定的8位或16位位移量采用补码形式表示。在计算有效地址时,如果位移量是8位,那么被带符号扩展成16位。当所得的有效地址超过FFFFH时,就取其64K的模。
例如, MOV AX, [BX DI-2]
假设, (DS)=5000H,(BX)=1223H,(DI)=54H
那么,存取的物理存储单元式51275H。再设该字存储单元的内容是7654H,那么在执行该指令后,(AX)=7654H。图2.11反映该指令的存储和执行情况,位移用补码表示。
图2.11 相对基址加变址寻址方式示意图
尽管相对基址加变址这种寻址方式最复杂,但也是最灵活。
相对基址加变址寻址这种寻址方式的表示方法多种多样,下面四种表示方法是等价的:
MOV AX,[BX DI 1234H]
MOV AX,1234H[BX DI]
MOV AX,1234H,[BX][DI]
MOV AX,1234H[DI][BX]
2.4 8086/8088指令系统
本节详细介绍8086/8088指令集中的部分常用指令。
2.4.1 指令集说明
1. 分组
与早前的8位微处理器相比,8086/8088的指令系统丰富,而且指令的功能也强。大多数指令既能处理字数据,又能处理字节数据;算术运算和逻辑运算不局限于累加器,存储器操作数也可直接参加算术逻辑运算。
8086/8088的指令系统可分为如下六个功能组:
(1) 数据传送;
(2) 算术运算;
(3) 逻辑运算;
(4) 串操作;
(5) 程序控制;
(6) 处理器控制。
2. 指令表示格式
为了方便地介绍指令系统中的指令,我们先介绍汇编语言中指令语句的一般格式。在汇编语言中,指令语句可有四部分组成,一般格式如下:
[标号:] 指令助记符 [操作数 1 [操作数 2 ]] [;注释]
指令是否带有操作数,完全取决于指令本身,有的指令无操作数,有的指令有操作数,有的指令只有一个操作数,有的指令有需要两个操作数。标号的使用取决于程序的需要,是否写上注释由程序员决定。请注意:标号只被汇编程序识别,他与指令本身无关;由分号引导的注释则纯粹是为了理解和阅读程序的需要,汇编程序将其全部忽略,绝对不影响指令。
3. 其他说明
对于每一条指令,程序员要注意以下几点:
a) 指令的功能;
b) 适用于指令的操作数寻址方式;
c) 指令对标志的影响;
d) 指令的长度和执行时间。
2.4.2 数据传送指令
数据传送指令负责把数据、地址或立即数传送到寄存器或存储单元中。它又可以分为五种,分别说明如下:
1. MOV 传送指令
MOV 传送指令是使用的最频繁的指令,其格式如下:
MOV DST,SRC
此指令把一个字节或一个字从源操作数SRC送至目的操作数DST。
源操作数可以是累加器、寄存器、存储单元以及立即数,而目的操作数可以是累加器、器存器和存储单元。传送不改变源操作数。
图2.12 MOV指令数据传送方向示意图
MOV指令可实现的传送方向如图2.12所示。具体地说,数据传送指令能实现下列传送功能:
1)CPU内部寄存器的数据传送。例如:
MOV AH,AL
MOV BP,SP
MOV AX,CS
2)立即数送至通用寄存器或存储单元(各种存储器寻址方式)。例如:
MOV AL,3
MOV SI,-5
MOV VARB,-1 ;VARB是变量名,代表一个存储单元
MOV VARW,3456H ;VARW是一个字变量
MOV [SI],6543H
注意:立即数不能直接传送到段寄存器,立即数永远不能作为目的操作数。
3)寄存器与存储器间的数据传送。例如:
MOV AX,VARW ;VARW 是一个字变量
MOV VARW,DS
对存储器操作数而言,可采用各种存储器寻址方式,这一点对其他指令也一直成立。关于MOV指令,除了前面的例外,还要遵守下列规定:
1 源操作数和目的操作数类型要一致。即同时为字节或字,不能一个是字节,另一个是字。
2 除了串操作指令位,源操作数和目的操作数不能同时是存储器操作数。
这些例外和规定不仅适用于MOV指令,也同样适用于所有涉及到操作数的指令。
如果要在两个存储单元件传送数据,那么可利用通用寄存器过渡的方法进行,例如:
MOV AX,VARW1 ;把字变量VARW1的内容送到字变量VARW2
MOV VARW2,AX
这种利用通用寄存器过渡的方法,也适用于段寄存器间的数据传送。例如:
MOV AX,CS ;把CS的内容送到DS
MOV DS,AX
3. 交换指令
利用交换指令可方便地实现通用寄存器与通用寄存器或存储单元间的数据交换。交换指令的格式如下:
XCHG OPRD1,OPRD2
此指令把操作数OPRD1的内容与操作数OPRD2的内容交换。操作数同时是字节或字。OPRD1和OPRD2可以是通用寄存器和存储单元。但不包括段寄存器,也不能同时是存储单元,不能有立即数。可采用各种存储器寻址方式。例如:
XCHG AL,AH
XCHG [SI BP 3],BX
4. 地址传送指令
8086/8088有如下三条传送指令。
1)指令LEA(Load Effective Address)
指令LEA称为传送有效地址指令,其格式如下:
LEA REG,OPRD
该指令把操作数OPRD的有效地址传送到操作数REG。操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位的通用寄存器。例如:
LEA AX,BUFFER ;BUFFER是变量名
LEA DX,[BX 3]
请注意,LEA指令与把存储单元中的数据传送到寄存器的MOV指令有本质上的区别。假设变量BUFFER的偏移是1234H,该自变量的值为5678H,那么执行完指令“LEA AX,BUFFER”后,AX寄存器中的值为1234H,而不是5678H,在执行完指令“MOV AX,BUFFER”后,AX寄存器中的值为5678H,而不是1234H。
2)指令LDS(Load pointer into DS)
段值和段内偏移构成32位的指针地址。该指令传送32位地址指针,其格式如下:
LDS REG,OPRD
该指令把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS,把偏移部分送到指令给出的通用寄存器REG。操作数OPRD必须是一个32位的存储器操作数,操作数REG可以是一个16位的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器。例如:
LDS DS,[BX]
LDS SI,FARPOINTER ;FARPOINTER是一个双字变量
假设双字变量FARPOINTER包含的32位地址指针的段值为5678H,偏移为1234H,那么在执行指令“LDS SI,FARPOINTER”后,段寄存器DS的值为5678H,寄存器SI的值为1234H。32位地址指针的偏移部分存储在双字变量的低地址字中,段值部分存储在高地址字中。图2.13时该指令的执行示意图。
(3)指令LES(Load pointer into ES)
LES指令也传送32位地址指针,其格式如下:
LES REG,OPRD
该指令把操作数OPRD中所含的32位地址指针的段值部分送到附加段寄存器ES,把偏移部分送到指令给出的通用寄存器REG。其他说明同指令LDS。
5. 堆栈操作指令
在8086/8088系统中,堆栈是一段RAM区域。称为栈底的一端地址较大,称为栈顶的一端地址较小。堆栈的段值在堆栈段寄存器SS中,堆栈指针寄存器SP始终指向栈顶。只要重新设置SS和SP的初值(例如用MOV指令),就可以改变堆栈的位置。堆栈的深度由SP的初值决定。
堆栈操作始终遵守“后进先出”的原则,所有数据的存入和取出都在栈顶进行。在8086/8088系统中,进出堆栈的数据均以字为单位。
我们先列出堆栈的如下主要用途,每种用途的具体使用情况在以后的章节中陆续作介绍:
1)现场和返回地址的保护;
2)寄存器内容的保护;
3)传递参数;
4)寄存局部变量;
堆栈操作指令分为两种:进栈指令PUSH和出栈指令POP。
1) 进栈指令PUSH
进栈指令把16位数据压入堆栈,其格式如下:
PUSH SRC
指令把源操作数SRC压入堆栈。它先把堆栈指针寄存器SP的值减2,然后把源操作数SRC送入由SP所指的栈顶。图2.14(a)和(b)示意指令“PUSH AX”执行前后堆栈的变化情况,假设AX=8A9BH。随着压入堆栈的数据增多,堆栈也逐步扩展。SP值随着压栈而减小,但每次操作完,SP总是指向栈顶。当把一个16位数据压入堆栈时,总是遵守“高高低低”的存储原则。
源操作SRC可以是通用寄存器和段寄存器,也可以是字存储单元。例如:
PUSH SI
PUSH DS
PUSH VARW ;VARW是字变量
图2.14进栈和出栈操作示意图
PUSH [SI]
2)出栈指令POP
出栈指令从堆栈弹出16位数据,其格式如下:
POP DST
该指令从栈顶弹出一个字数据到目的操作数DST。它先把堆栈指针寄存器SP所指的字数据送至目的操作数DST,然后SP值加2,使其仍指向栈顶。图2.14(b)和(c)示意执行指令“POP AX”前后的堆栈变化情况。随着弹出堆栈的数据增多,堆栈也逐步收缩。SP值随着弹出操作而增大,但每次操作完,SP总是指向栈顶。
目的操作数DST可以是通用寄存器和段寄存器(但CS例外),也可以是字存储单元。例如:
POP [SI]
POP VARW ;VARW是字变量
POP ES
POP SI
下面的程序段说明堆栈的一种用途,临时保存寄存器的内容:
PUSH DS ;保护DS
PUSH CS
POP DS ;使DS的内容与CS的内容相同
…… ;其他操作
POP DS ;恢复DS