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"