这一节讲解8086/8088寻址方式,所谓寻址方式,就是寻找操作数或操作数地址的方式。
寻址方式
8086/8088有七种基本的寻址方式:立即寻址,寄存器寻址,直接寻址,寄存器间接寻址,寄存器相对寻址,基址变址寻址,相对基址变址寻址。
其中,后五种寻址方式(即直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址和相对基址变址寻址)属于存储器寻址,用于说明操作数或操作数地址所在存储单元的地址。这五种方式也就是确定存放操作数的存储单元有效地址EA的方法,这里所说的有效地址就是在前面一节讲存储器分段中所说的段内偏移地址。
除了这些基本的寻址方式以外,还有固定寻址和I/O端口寻址等,但不会在本节中介绍到。
基本寻址方式
下面重点说一下这七种基本寻址方式的特点:
1. 立即寻址方式
先解释一个概念,叫做立即数。
操作数包含在指令中,它作为指令的一部分,跟在操作码后存放在代码段。这种操作数称为立即数。
立即寻址方式所提供的操作数紧跟在操作码后面,与操作码一起放在指令代码段中,不需要到其他地址单元中去取。立即数可以是8位,也可以是16位。这种寻址方式主要用于给寄存器或存储单元赋初值的场合。立即寻址方式是这七种寻址方式中速度最快的寻址方式。
举例:MOV AX, 1234H ; 给AX寄存器赋值为1234H
2. 寄存器寻址方式
寄存器寻址的特点是操作数在CPU内部的寄存器中,在指令中指定寄存器号。
对于16位操作数,寄存器可以是AX、BX、CX、DX、SI、DI和SP等;
对于8位操作数,寄存器可以是AL、AH、BL、BH、CL、CH、DL和DH。
例如:MOV SI, AX
MOV AL, DH
由于操作数在寄存器中,不需要通过访问存储器来取得操作数,所以采用寄存器寻址方式的指令执行速度较快。
3. 直接寻址方式
直接寻址的操作数在存储器中,指令直接包含有操作数的有效地址。由于操作数一般存放在数据段,所以操作数的地址由DS加上指令中给出的16位偏移得到。
假如DS内容是5000H,地址为51234H字存储单元中的内容时6789H,那么在执行“MOV AX, [1234H]”后寄存器AX的内容是6789H。
由于该指令所用的段寄存器为DS,所以该条指令还可以写为"MOV AX, DS:[1234H]"。
当然,除了DS段寄存器以外,还可以指定其他段寄存器。
例如:MOV ES:[5678H], BL ; 指定ES作为段寄存器
这种寻址方式常用于处理单个存储器变量的情况。它可以实现在64K字节的段内寻找操作数。直接寻址的操作数通常是程序使用的变量。
4. 寄存器间接寻址方式
寄存器间接寻址的操作数在存储器中,操作数有效地址在SI、DI、BX、BP这四个寄存器之一中。在一般情况下,如果有效地址在SI、DI和BX中,则以DS段寄存器的内容为段值;如果有效地址在BP中,则以SS段寄存器的内容为段值。
例如:MOV AX, [SI] ; 自动引用DS作为段寄存器
假设 (DS)= 5000H, (SI)= 1234H
那么存储的物理存储单元地址是51234H。再设该字存储单元的内容是6789H,那么在执行该指令后,(AX)= 6789H。
当然也可以指定段超越前缀,如:
MOV DL, CS:[BX] ;引用的段寄存器是CS
如果有效地址在BP中,那么引用的段寄存器为SS。如:
MOV [BP], CX ;此时引用的段寄存器是SS
这种寻址方式可以用于表格处理,在处理完表中的一项后,只要修改指针寄存器的内容就可以方便地处理表中的另一项。
注意同寄存器寻址方式的书写方式予以区别。
5. 寄存器相对寻址方式
操作数在存储器中,操作数的有效地址是一个基址寄存器(BX、BP)或变址寄存器的(SI、DI)内容加上指令中给定的8位或16位位移量之和。
即 EA = (BX)或(BP)或(SI)或(DI) + 8位或16位位移量
在一般情况下,如果SI、DI或BX的内容作为有效地址的一部分,那么引用的段寄存器是DS。如:
MOV AX, [DI+1223H] ; 引用的段寄存器是DS
假设,(DS)= 5000H,(DI)= 3678H。
那么,存取的物理存储单元地址是5489BH。再假设该字存储单元的内容是55AAH,那么在执行该指令后,(AX)= 55AAH。
而当BP的内容作为有效地址一部分时,那么引用的段寄存器是SS,如:
MOV BX, [BP-4] ; 引用的段寄存器是SS
当然也可以自行指定段寄存器,如:
MOV ES:[BX+5], AL ; 引用ES作为段寄存器
这种寻址方式同样可用于表格处理,表格的首地址可设置为指令中的位移量,利用修改基址或变址寄存器的内容来存取表格中的项值。
以下两种写法等价:
MOV AX, [SI+3]
MOV AX, 3[SI]
6. 基址变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器之一的内容与变址寄存器之一的内容相加得到。
即:EA = (BX)或(BP) + (SI)或(DI)
在一般情况下,如果BP的内容作为有效地址的一部分,则以SS的内容作为段值,否则以DS的内容作为段值。
当所得的有效地址超过FFFFFH时,就取其64K的模。
例如: MOV AX, [BX+DI] ; 此时引用DS段寄存器
假设,(DS)= 5000H,(BX)= 1223H, (DI)= 54H
那么,存取的物理存储单元地址是51277H。再假设改字存储单元的内容是168H,那么在执行该指令后,(AX)= 168H
当然,还可以增加段超越前缀来指定段寄存器。
例如:
MOV AX, ES:[BX+SI] ; 引用ES作为段寄存器
MOV DS:[BP+SI], AL ; 引用DS作为段寄存器
这种寻址方式适用于数组或表格处理。用基址寄存器存放数组首地址,而用变址寄存器来定位数组中的各元素,或反之。
另外,以下两种表示方法是等价的:
MOV AX, [BX+DI]
MOV AX, [DI][BX]
7. 相对基址变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器之一的内容与变址寄存器之一的内容及指令中给定的8位或16位位位移量相加得到。
即:EA = (BX)或(BP) + (SI)或(DI) + 8位或16位位移量
在一般情况下,如果BP作为有效地址的一部分,则以SS段寄存器的内容为段值,否则以DS段寄存器的内容为段值。
在指令中给定的8位或16位位移量采用补码形式表示。在计算有效地址时,如果偏移量是8位,那么被带符号扩展成16位。当所得的有效地址超过FFFFH时,就取其64K的模。
举例:MOV AX, [BX+DI-2] ; 自动引用DS作为段寄存器
假设,(DS)= 5000H,(BX)= 1223H, (DI)= 54H
那么,存取的物理存储单元地址是51275H。再设该字存储单元的内容是7654H,那么在执行该指令后,(AX)= 7654H
以下四种表示方法均是等价的:
MOV AX, [BX+DI+1234H]
MOV AX, 1234H[BX+DI]
MOV AX, 1234H[BX][DI]
MOV AX, 1234H[DI][BX]
尽管相对基址变址这种寻址方式最复杂,但也是最灵活的。