7.3 寻址方式
寻址方式是确定本条指令的操作数地址、下一条要执行指令的指令地址。
一、指令寻址
1.顺序寻址:(PC)+1àPC
2.跳跃寻址:由转移指令指出下一条指令地址。
二、数据寻址
指令格式:
操作码 | 寻址特征 | 形式地址A |
形式地址:指令字中的地址。
有效地址:操作数的真实地址。
我们做如下约定,指令字长=存储字长=机器字长
1.立即寻址
形式地址A就是操作数,直接参与操作码指定的运算。指令形式变成如下:
操作码 | # | A |
其中#是立即寻址特征,A是立即数,可正可负(补码表示)。在指令执行阶段不访存,A的位数限制了立即数的范围。
2.直接寻址
EA=A,有效地址由形式地址直接给出。如图3.1所示。
图3.1 直接寻址方式
执行阶段访问一次存储器(就可以直接获取到操作数地址),A的尾数决定了该指令操作数的寻址范围。操作数的地址不易修改(必须修改A)。
3.隐含寻址
操作数地址隐含在操作码中。
图3.2 隐含寻址
如8086,
MUL指令 | 被乘数隐含在AX(16位)或AL(8位)中 |
MOVS指令 | 源操作数的地址隐含在SI中,目的操作数的地址隐含在DI中。 |
指令字中少了一个地址字段,可缩短指令字长。
4.间接寻址
EA=(A),有效地址由形式地址间接提供。如图3.3所示。
图3.3 间接寻址
对于一次间接寻址来说,它执行指令阶段2次访存,可扩大寻址范围,便于编制程序。对于多次间接寻址来说,其不同是需要多次访存。
5.寄存器寻址
EA=Ri,有效地址即为寄存器编号。如图3.4所示。它的特点是:
①执行阶段不访存,只访问寄存器,执行速度快;
②寄存器个数有限,可缩短指令字长。
图3.4 寄存器寻址
6.寄存器间接寻址
EA=(Ri),有效地址存在寄存器中。如图3.5所示。
图3.5 寄存器间接寻址
它有以下特点:
①有效地址在寄存器中,操作数在存储器中,执行阶段访存;
②便于编制循环程序。
7.基址寻址
(1)采用专用寄存器作基址寄存器
EA=(BR)+A,BR为基址寄存器。如图3.6所示。
图3.6 专用寄存器作基址寄存器
它有以下特点:
①可扩大寻址范围;
②有利于多道程序;
③BR内容由操作系统或管理程序确定;
④在程序的执行过程中BR内容不变,形式地址A可变。
(2)采用通用寄存器作基址寄存器
图3.7 通用寄存器作基址寄存器
它有以下特点:
①由用户指定哪个通用寄存器作基址寄存器;
②基址寄存器的内容由操作系统确定;
③在程序的执行过程中R0内容不变,形式地址A可变。
8.变址寻址
EA=(IX)+A
IX为变址寄存器(专用),通用寄存器也可以作为变址寄存器。
图3.8 变址寻址
它有以下特点:
①可扩大寻址范围;
②IX的内容由用户给定;
③在程序的执行过程中IX内容可变,形式地址A不变;
④便于处理数组问题。
例:设数据块首地址为D,求N个数的平均值。
解答过程如图3.9所示。
图3.9 例的图解
9.相对寻址
EA=(PC)+A
A是相对于当前指令的位移量(可正可负,以补码形式保存)。如图3.10所示。
图3.10 相对寻址
它有以下特点:
①A的位数决定操作数的寻址范围;
②程序浮动(程序在内存当中位置变化);
③广泛用于转移指令。
上例用相对寻址的实现,如图3.11所示。
图3.11 上例用相对寻址实现
我们注意M随程序所在存储空间的位置不同而不同,但是指令BNE *-3与指令ADD X,D相对位移量不变(*为相对寻址特征)。指令BNE *-3操作数的有效地址为EA=(M+3)-3=M。
(1)按字节寻址的相对寻址举例
图3.12 按字节寻址的相对寻址举例
设当前指令地址为PC=2000H,转以后的目的地址为2008H。因为取出JMP*+8后,PC的地址已经跳转到2002H了,所以JMP*+8指令的第二字节为2008H-2002H=06H。
10.堆栈寻址
(1)堆栈的特点
堆栈包括硬堆栈(多个寄存器)和软堆栈(指定的存储空间)。
先进后出(一个出入口)。栈顶地址由SP指出。进栈(SP)-1àSP,出栈(SP)+1àwidth=”437″ height=”132″一般来说,栈底地址最高,栈顶地址最小,所以进栈才会-1,出栈才会+1。
(2)堆栈寻址举例
图3.13 堆栈寻址举例
假如说要PUSH A,在执行PUSH之前,栈顶是SP=200H,保存着X,ACC为15。PUSH以后,先将SP-1=1FFH,然后把ACC中的15压入到栈顶(1FFH)。
假如说要POP A。POP A之前,SP=1FFH,ACC中保存的为Y。先把15送入到ACC,然后栈顶下压变为200H。
(3)SP修改与主存编址方法有关
①按字编址:进栈:(SP)-1->SP;出栈:(SP)+1->SP;
②按字节编址:
若存储字长16位,进栈:(SP)-2->SP;出栈:(SP)+2->SP;
若存储字长32位,进栈:(SP)-4->SP;出栈:(SP)+4->width=”437″ height=”132″