Alex_McAvoy

想要成为渔夫的猎手

指令寻址方式

【指令寻址与数据寻址】

寻址

寻址方式是指寻找指令或操作数有效地址的方式,也就是指确定本条指令的数据地址,以及下一条将要执行的指令地址的方法

指令中的地址码字段并不代表操作数的真实地址,称为形式地址 $(A)$,用形式地址并结合寻址方式,可以计算出操作数在存储器中的真实地址,称为有效地址 $(EA)$

形式地址 $(A)$ 表示地址为 $A$ 的数值,$A$ 既可以是寄存器编号也可以是内存地址,对应的 $(A)$ 就是寄存器中的数值,或相应内存单元的数值,例如:$EA=(A)$ 的意思就是有效地址是地址A中的数值

寻址方式分为指令寻址和数据寻址两大类,寻找下一条将要执行的指令地址称为指令寻址,寻找操作数的地址称为数据寻址

指令寻址

指令寻址方式有两种:

  • 顺序寻址:通过程序计数器 $PC$ 自动 $+1$(一个指令字长),自动形成下一条指令的地址
  • 跳跃寻址:通过转移类指令实现,即下条指令的地址码不是由程序计数器给出,而是由本条指令给出下条指令地址的计算方式,跳跃到的地址分为绝对地址(由标记符直接得到)和相对地址(对于当前指令地址的偏移量),跳跃的结果是当前指令修改 $PC$ 值,所以下一条指令仍然是通过程序计数器 $PC$ 给出

数据寻址

数据寻址就是如何在指令中表示一个操作数的地址,如何用这种表示得到操作数或怎样计算出操作数的地址

数据寻址方式的种类较多,为了区别各种方式,通常在指令字中设一个字段,用来指明属于哪种寻址方式

由此可得指令的格式如下所示:

【数据寻址方式】

数据寻址方式对比

下表给出了数据寻址方式的有效地址和访存次数的对比

寻址方式 有效地址 访存次数
隐含寻址 程序指定 $0$
立即寻址 $A$ 即操作数 $0$
直接寻址 $EA=A$ $1$
一次间接寻址 $EA=(A)$ $2$
寄存器寻址 $EA=R_i$ $0$
寄存器间接寻址 $EA=(R_i)$ $1$
相对寻址 $EA=(PC)+A$ $1$
基址寻址 $EA=(BR)+A$ $1$
变址寻址 $EA=(IX)+A$ $1$

隐含寻址

这种类型的指令,不是明显地给出操作数的地址,而是在指令中隐含着操作数的地址

如单地址的指令格式,就不是明显地在地址字段中指出第二操作数的地址,而是规定累加器 $ACC$ 作为第二操作数地址,指令格式明显指出的仅是第一操作数的地址,因此,累加器 $ACC$ 对单地址指令格式来说是隐含地址

该方式有利于缩短指令字长,但需要增加存储操作数或隐含地址的硬件

立即寻址

这种类型的指令的地址字段指出的不是操作数的地址,而是操作数本身,又称为立即数,此外,数据是采用补码形式存放的

立即寻址在指令执行阶段不访问主存,指令执行时间最短,但是 $A$ 的位数限制了立即数的范围

直接寻址

指令字中的形式地址 $A$ 就是操作数的真实地址 $EA$,即 $EA=A$

该方式简单便捷,指令在执行阶段仅访问一次主存,不需要专门计算操作数地址,但 $A$ 的位数决定了该指令操作数的寻址范围,操作数的地址不易修改

间接寻址

间接寻址是相对于直接寻址而言的,指令的地址字段给出的形式地址不是操作数的真正地址,而是操作数有效地址所在的存储单元的地址,也就是操作数地址的地址,即:$EA=(A)$

间接寻址可扩大寻址范围,可以方便地完成子程序返回,便于编制程序,但指令在执行阶段要多次访存,由于访问速度过慢,这种寻址方式并不常用

寄存器寻址

在指令字中直接给出操作数所在的寄存器编号,即 $EA=R_i$,其操作数在由 $R_i$ 所指的寄存器内

该方式在指令执行阶段不访问主存,只访问寄存器,因寄存器数量较少,对应地址码长度较小,使得指令字短且因不用访存,所以执行速度快,同时支持向量/矩阵运算,但寄存器价格昂贵,计算机中寄存器个数有限

寄存器间接寻址

寄存器间接寻址是指在寄存器 $R_i$ 中给出的不是一个操作数,而是操作数所在主存单元的地址,即 $EA=(R_i)$

寄存器间接寻址与一般间接寻址相比速度更快,但由于操作数在主存中,因此指令的执行阶段需要访问主存

相对寻址

相对寻址是把程序计数器 $PC$ 的内容加上指令格式中的形式地址 $A$ 而形成操作数的有效地址,即 $EA=(PC)+A$,其中 $A$ 是相对于当前指令地址的位移量,该位移量用补码表示,同时其位数决定操作数的寻址范围

该寻址方式的操作数的地址不是固定的,它随着 $PC$ 值的变化而变化,并且与指令地址之间总是相差一个固定值,因此便于程序浮动,广泛应用于转移指令

需要注意的是,对于转移指令 $JMPA$,当 CPU 从存储器中取出一个字节时,会自动执行 $(PC)+1\rightarrow PC$,若转移指令的地址为 $X$,且占 $2$ 个字节,在取出该指令后,$PC$ 的值会增 $2$,即 $(PC)=X+2$,这样在执行完该指令后,会自动跳转到 $X+2+A$ 的地址继续执行

基址寻址

基址寻址是将 CPU 中基址寄存器 $BR$ 的内容加上指令格式中的形式地址 $A$,而形成操作数的有效地址,即 $EA=(BR)+A$,其中基址寄存器既可采用专用寄存器,也可采用通用寄存器

基址寄存器是面向操作系统的,其内容由操作系统或管理程序确定,主要用于解决程序逻辑空间与存储器物理空间的无关性,在程序执行过程中,基址寄存器的内容作为基地址不变,而形式地址作为偏移量可变

当采用通用寄存器作为基址寄存器时,可由用户决定哪个寄存器作为基址寄存器,但其内容仍由操作系统确定

基址寻址可扩大寻址范围,用户不必考虑自己的程序存于主存的哪一空间区域,故有利于多道程序设计,以及可用于编制浮动程序,但作为偏移量的形式地址 $A$ 的位数较短

变址寻址

有效地址 $EA$ 等于指令字中的形式地址 $A$ 与变址寄存器 $IX$ 的内容相加之和,即 $EA=(IX)+A$,其中 $IX$ 为变址寄存器,也可用通用寄存器作为变址寄存器

变址寄存器是面向用户的,在程序执行过程中,变址操作数寄存器的内容作为偏移量可由用户改变,形式地址 $A$ 作为基地址不变

该方式可扩大寻址范围,同时在数组处理过程中,可设定 $A$ 为数组的首地址,不断改变变址寄存器 $IX$ 的内容,便可很容易形成数组中任一数据的地址,特别适合编制循环程序

显然,变址寻址与基址寻址的有效地址形成过程极为相似,但从本质上来讲,两者有较大区别,基址寻址面向系统,主要用于为多道程序或数据分配存储空间,故基址寄存器的内容通常由操作系统或管理程序确定,在程序的执行过程中其值不可变,而指令字中的 $A$ 是可变的,变址寻址立足于用户,主要用于处理数组问题,在变址寻址中,变址寄存器的内容是由用户设定的,在程序执行过程中其值可变,而指令字中的 $A$ 是不可变的

堆栈寻址

堆栈是存储器中一块特定的按后进先出 LIFO 原则管理的存储区,该存储区中被读/写单元的地址是用一个特定的寄存器给出的,该寄存器称为堆栈指针 $SP$

堆栈可分为硬堆栈与软堆栈两种:

  • 硬堆栈:即寄存器堆栈,成本比较高,不适合做大容量的堆栈
  • 软堆栈:从主存中划出一段区域来做堆栈

在采用堆栈结构的计算机系统中,大部分指令表面上都表现为无操作数指令的形式,因为操作数地址都隐含使用了 $SP$,通常情况下,在读/写堆栈中的一个单元的前后都伴有自动完成对 $SP$ 内容的增量或减量操作

感谢您对我的支持,让我继续努力分享有用的技术与知识点!