80X86的指令系统和寻址方式
计算机解决实际问题是通过执行指令序列实现的。指令中所要完成的操作表现为操作码,其它表现为与操作数或操作数地址有关的信息。形式为: 操作码 操作数 ......操作数
所谓寻址方式指的是指令按什么方式寻找到所需的操作数或与其有关的信息。
与数据有关的寻址方式
这种寻址方式用来确定操作数地址从而找到操作数。我们以数据传送指令MOV为例来说明。其汇编格式为: mov 目标, 源(源->目标)
1.立即寻址方式(immediate addressing)
操作数直接包含在指令中,紧跟在操作码之后的寻址方式称为立即寻址方式,把该操作数称为立即数。
MOV AL, 6 ;(AL)=6
MOV AX, 3064H ;(AX)=3064H
这种寻址方式只能出现在源操作数的位置。其它寻址方式既可以出现在源也可以出现在目标操作数位置。
2.寄存器寻址方式(register addressing)
操作数直接包含在寄存器中,由指令指定寄存器号的寻址方式。
MOV BX, AX ;(BX)=(AX)
MOV DI, 5678H ;(DI)=5678H
除以上两种寻址方式外,以下各种寻址方式的操作数都在存储器中,其操作数称为存储器操作数。
由于80X86对内存采用分段管理,因此由以下寻址方式得到的只是有效地址(简写为EA-effective address,在IBM PC中就是操作数地址的偏移量部分)。
有效地址可以由以下四种成分组成:
*位移量(displacement)是存放在指令中的一个8位、16位或32位的数,它是一个地址。
*基址(base)是存放在基址寄存器中的内容。通常用来指向数据段中数组或字符串的首地址。
*变址(index)是存放在变址寄存器中的内容。通常用来访问数组中的某个元素或字符串中的某个字符。
*比例因子(scale factor)是80386以上CPU新增加的。其值可为1、2、4或8。寻址中,可用变址寄存器的内容乘以比例因子来取得变址值。
EA = 基址+(变址×比例因子)+位移量
在某些情况下,80X86允许程序员用段跨越前缀来改变系统所指定的默认段。格式为“段寄存器名:”。
但在以下三种情况下,不允许使用段跨越前缀:
o 串处理指令的目的串必须用ES段。
o PUSH指令的目的和POP指令的源必须用SS段。
o 指令必须存放在CS段中。
上页EA的计算公式中,等号右边的四种成分可以任意组合使用,在各种不同组合下其中每一种成分均可空缺,但比例因子只能与变址寄存器同时使用,这样就可得到以下6种不同组合的访问存储器的数据寻址方式。
3.直接寻址方式(direct addressing)
操作数的有效地址直接包含在指令中的寻址方式。
有效地址存放在代码段的指令操作码之后,但操作数
本身在存储器中,所以必须先求出操作数的物理地址。这
种寻址方式常用于存取简单变量。
MOV AL, [78H]
在实模式中,若DS = 3000H,(30078H)= 12H。则DS:78H表示物理地址30078H,该指令的执行结果是(AL)= 12H 。
直接寻址方式可以使用段跨越前缀,如
MOV AL, ES:[78H]。
由于在汇编语言中用符号表示地址,所以指令“MOVAL,VAR”中的源操作数寻址方式是直接寻址,VAR是内存的符号地址。如写成“MOV AL,[VAR]”也可以,两者是等效的。
直接寻址方式适用于处理单个变量。80X86中为了使指令字不要过长,规定双操作数指令的两个操作数中,只能有一个使用存储器寻址方式,这就是一个变量常常先要送到寄存器的原因。
4.寄存器间接寻址方式(registerindirect addressing)
操作数的有效地址在基址寄存器BX、BP或变址寄存器SI、DI中,而操作数在存储器中的寻址方式。对于386以上CPU,允许使用任何32位通用寄存器。凡使用BP、ESP和EBP时,其默认段为SS段(缺省情况操作数在堆栈段)。其它寄存器的默认段为DS寄存器(缺省情况操作数在数据段) 。这两种情况都允许使用段超越前缀。
例: MOV AL, [BX]
注意BX用[ ]括起来,表示BX寄存器中是有效地址而不是操作数,这也是与寄存器寻址方式在汇编格式上的区别。
若(DS)=3000H,(BX)=78H,(30078H)=12H,则物理地址为:10H*3000H+78H=30078H,执行结果:(AL)=12H。
例: MOV AX, [BP]
若(SS)=2000H,(BP)=80H,(20080H)=12H,(20081H)=56H, 执行结果: (AX)=5612H。
利用这种寻址方式再配合修改寄存器内容的指令可以方便地处理一维数组。
5.寄存器相对寻址方式(register relative addressing)
也称为直接变址寻址方式。操作数的有效地址是一个基址(BX、BP)或变址(SI、DI)寄存器的内容和指令中给定的一个位移量(disp)之和。有效地址由2部分组成。对于386以上允许使用任何32位通用寄存器。
即:EA=(基址<或变址>寄存器)+disp
或:EA=(32位通用寄存器)+disp (386型号以上)
例: MOV AL, 8[BX] 或MOV AL, [BX+8]
若(DS)= 3000H,(BX)= 70H,(30078H)= 12H
则物理地址=10H×(DS)+(BX)+8=30078H,结果(AL)=12H。
例:MOV AX, COUNT[SI] 或MOV AX, [COUNT+SI]
其中COUNT为16位位移量的符号地址。
若(DS)= 3000H,(SI)= 2000H,COUNT=3000H
则物理地址=10H×(DS)+(SI)+COUNT=35000H。
使用这种寻址方式可以访问一维数组,其中COUNT是数组起始地址的偏移量,寄存器中是数组元素的下标乘以元素的长度(一个元素占用的字节数),下标从0开始计数。
寄存器相对寻址方式允许使用段跨越前缀。
6.基址变址寻址方式(based indexed addressing)
操作数的有效地址是一个基址寄存器(BX、BP)和一个变址寄存器(SI、DI)的内容之和。386以上允许使用变址部分除ESP以外的任何两个32位通用寄存器组合。
缺省使用段寄存器的情况由基址寄存器决定。允许使用段超越前缀。
例: MOV AL,[BX][SI] 或MOV AL,[BX+SI]
AL = DS * 10H + BX + SI
使用这种寻址方式可以访问一维数组,其中BX存放数组起始地址的偏移量,SI存放数组元素的下标乘以元素的长度,下标从0开始计数。
7.相对基址变址寻址方式(relative based indexed addressing)
例:MOV AL,MASK[BX][SI] 或MOV AL,MASK[BX+SI] 或MOV AL,[MASK+BX+SI]
AL = DS * 10H + MASK + BX + SI
这种寻址方式通常用于对二维数组的寻址。如存储器中存放着由多个记录组成的文件,则位移量可指向文件之首,基址寄存器指向某个记录,变址寄存器则指向该记录中的一个元素。
8.比例变址寻址方式(scaled indexed addressing)
注意:80386以上的微处理器才提供。
EA=(基址寄存器)+(变址寄存器)×比例因子+disp
其优点在于:对于元素大小为2、4、8字节的数组,可以在变址寄存器中给出元素下标,而由寻址方式控制直接用比例因子把下标转换为变址值。
<b>可以看出,它实际上是386以上CPU存储器操作数寻址方式的通用公式。</b>