本节内容:基址加变址寻址方式。
■基址加变址寻址方式:指令操作数为内操作数,操作数地址使用[基址寄存器+变址寄存器]表示。
7.6.1 基址加变址寻址方式
基址加变址寻址方式的操作数在存储器中,操作数的有效地址由基地址寄存器(BX,BP)之一与变址寄存器(SI,DI)之一相加得到,如图7-12所示。
通常BX、SI、DI引用DS,BP引用SS。
图7-12 基址加变址地址表达式
如果所得地址超出FFFFH,则取其64K(FFFFH)的模。
如图7-13所示:
图7-13 基址加变址寻址方式
假设DS=5000H,BX=3456H,DI=1234H
MOV AX,[BX+DI]语句中的[BX+DI]内存操作数的物理地址为5468AH,AX=5678H。
动手实验22:演示基址加变址寻址方式
如图7-14所示,在debug调试器内输入:
mov ax,5000H
mov ds,ax;将段值5000H赋给ds段寄存器。
Mov bx,3456H;
Mov di,1234H;
Mov ax,[bx+di];将数据段偏移地址[bx+di]处存储的值送入ax寄存器。
图7-14 演示基址加变址寻址方式
在其他段中使用基址加变址寻址方式:
MOV DS:[BP+SI],AL ;将AL寄存器的值存入数据段[BP+SI]偏移地址处。
MOV AX,ES:[BX+SI] ;将附加段ES内偏移地址[BX+SI]处的数值送入AX寄存器。
基址加变址寻址方式通常用于数组或表格处理。用基址寄存器存放数组首地址,而变址寄存器用来定位数组中的元素,或相反。由于两个寄存器都可以改变,所以能更加灵活地访问数组或表格中的元素。
提示
如下两种方式等价:
MOV AX , [BX+DI]
MOV AX,[BX][DI]
7.7节 相对基址加变址寻址方式
本节内容:相对基址加变址寻址方式。
■相对基址加变址寻址方式:指令操作数为内存操作数,操作数的地址采用[基址寄存器+变址寄存器+位移量]的方式表示。示例代码address.asm。
7.7.1 相对基址加变址寻址方式
相对基址加变址寻址方式的操作数在存储器中,操作数的有效地址由基地址寄存器(BX,BP)之一与变址寄存器(SI,DI)之一的内容及指令中给定的8位或16位位移量相加得到,如图7-15所示。
通常BX,SI,DI引用DS,BP引用SS。
图7-15 相对基址加变址地址表达式
在指令中给定的8位或16位位移量如果是有符号整数,则采用补码形式表示。如果是8位有符号整数,则带符号位扩展成16位。
如果所得地址超出FFFFH,则取其64K(FFFFH)的模。
如图7-16所示:
图7-16 相对基址加变址寻址方式
例:假设(DS)=5000H,(BX)=3456H,[DI]=1234H。
那么MOV AX,[BX+DI-2] ;物理地址为54688H,(AX)=6789H。
动手实验23:演示相对基址加变址寻址方式
如图7-17所示,在debug调试器内输入:
mov ax,5000H
mov ds,ax;将段值5000H赋给ds段寄存器。
Mov word ptr [4688H],6789H;将6789H存入数据段偏移地址4688H处。
Mov bx,3456H;
Mov di,1234H;
Mov ax,[bx+di-2];将数据段偏移地址[bx+di-2]处存储的值送入ax寄存器。
图7-17 相对基址加变址寻址方式
举例
如表7-1所示,我们在数据定义中定义了一张学生统计表table,表内记录了学生student0开始的若干个学生统计信息。分别统计该名学生的姓名(8个字节)、年龄(1个字节)、学号(1个字节)、身高(2个字节)和体重(2个字节)。如果把这张表存入计算机的线性内存,每名学生需要14个字节的内存空间,且连续存储,如图7-18所示。
接下来我们使用合适的寻址方式来获取table表中的学习信息。
Table表的起始地址:mov bx,offset table;使用bx基址寄存器。
学生student0的地址:mov si,offset student0。
学生student1的地址:mov di,offset student1。
学生student0的姓名位于表table内的偏移地址[SI]处,或者表示为偏移地址[bx]。
学生student0的年龄位于表table内的偏移地址8处,或者表示为偏移地址[bx+8]。
学生student1的姓名位于表table内的偏移地址[di]处,表示为偏移地址[bx+di]。
学生student1的年龄位于表table内的偏移地址[di +8]处,表示为偏移地址[bx+di+8]。
如果继续使用变址寄存器SI,则表示如下:
add si,14;将SI的值加上14个字节,指向学生student1。
学生student1的姓名位于表table内的偏移地址[si]处,表示为偏移地址[bx+ si]。
学生student1的年龄位于表table内的偏移地址[si +8]处,表示为偏移地址[bx+ si +8]。
表7-1 相对基址加变址寻址方式
图7-18 内存中的学生统计表
尽管这种相对基址加变址寻址方式最复杂,但是也最灵活,其他6种寻址方式都是其变形。
提示
如下四种方式等价:
MOV AX , [BX+DI+1234H]
MOV AX , 1234H[BX+DI]
MOV AX,1234H[BX][DI]
MOV AX,1234H[DI][BX]
动手实验24:寻址方式
编写下面的示例代码address.asm源程序,完成编译链接,生成address.exe可执行程序,并在debug调试器中单步跟踪执行。仔细观察不同寻址方式计算的偏移地址。
示例代码2:
;程序名:address
;功能:寻址方式
;============================
assume cs:code,ds:data
X = 1234H ;X EQU 1234H
data segment
val1 db 1
val2 dw ?
val3 db 1,2,3,4,5,6,7,8,9,0,1,2,3
val4 dd 12345678h
data ends
code segment
start:
mov ax,data ;将段标号data送入ax
mov ds,ax ;ds=ax
;立即寻址方式
mov ax,X ;ax=1234H
mov word ptr val1,3456h;将3456H写入val1偏移地址处,val1=56h,val2=0034h
;寄存器寻址方式
mov cx,ax ;cx=ax
;直接寻址方式
mov al,byte ptr ds:[val1] ;将val1偏移地址处一个字节的值送入al,al=56h
mov al,val1 ;等同于上一条语句的简化形式
;寄存器间接寻址方式
mov si,offset val3 ;将val3偏移地址送入si,si=3
lea si,word ptr ds:[val3] ;将val3偏移地址送入si,si=3
add si,1 ;si=4
mov bx,word ptr ds:[si] ;将si偏移地址处一个字的值送入bx=0302h
;寄存器相对寻址方式
mov bx,offset val1 ;将val1偏移地址送入bx,bx=0
mov ax,ds:[bx+3] ;将数据段bx+3偏移地址处一个字的值送入ax,ax=0201h
;基址加变址寻址方式
mov si,1 ;si=1
mov bx,offset val3 ;将val3偏移地址送入bx,bx=3
mov ax,[bx+si] ;将[bx+si]=4偏移地址处的一个字的值送入ax,ax=0302h
;相对基址加变址寻址方式
mov ax,[bx+si+1] ;将[bx+si+1]=5偏移地址处的一个字的值送入ax,ax=0403h
;
lea si,val4 ;将val4偏移地址送入si,si=10H
mov si,offset val4 ;将val4偏移地址送入si,si=10H
mov al,byte ptr val4 ;将val4偏移地址处一个字节的值送入al,al=78h
mov al,byte ptr ds:[si] ;将si偏移地址处一个字节的值送入al,al=78h
;将val4偏移地址处5678H送入di,1234H送入ds
lds di,val4 ;ds=1234h,di=5678h
;切换回原数据段
mov ax,data
mov ds,ax
;
mov al,0 ;4C号功能入口参数
mov ah,4ch ;调用DOS 4C号功能,退出程序
mov ax,4c00h ;与前两条语句等价
int 21h
code ends
end start
编译后加载debug调试器后的反汇编代码如图7-19所示:
图7-19 address.asm反汇编代码
示例代码2给出了7种不同的寻址方式的示例。Debug调试器单步跟踪时,请读者仔细核对注释中给出的偏移地址是否正确。只有给出正确的地址,才可以正确的读写内存。我们可以简单将计算机的工作原理理解为查数、查表、查地址。随着学习的深入,请读者慢慢理解。
同时需要注意lea指令和mov指令的区别,lea指令取地址,而mov指令取值。Lds指令为复合指令,将四个字节的源操作数中的高字送入ds,低字送入di。我们随后将在下一章详细讲解8086计算机指令。
练习
1、8086的基本寻址方式分为哪三类?
2、8086存储器寻址方式可分为哪几种?
3、请说明如下指令中源操作数的寻址方式:
MOV BX,[1234H]
MOV BX,1234
MOV DX,BX
MOV DX,[BX]
MOV DX,[BX+1234H]
MOV DX,[BX+DI]
MOV DX,[BX+DI+1234H]
4、如何选择恰当的选择寻址方式?
5、为什么目标操作数不能采用立即寻址方式?
6、哪些存储器寻址方式可能导致有效地址超出64KB的范围?8086是如何处理的?
本文摘自编程达人系列教材《X86汇编语言基础教程》。