4-2指令系统-指令的寻址方式
文章目录
一.指令寻址
1.顺序寻址
通过程序计数器(PC)加1,自动生成下一条指令的地址。对于变长指令字结构等情况PC+n,也属于顺序寻址
2.跳跃寻址
通过转移类指令实现,是否跳跃受到状态寄存器和操作数的控制。
跳跃的地址分为
绝对地址:由标记符直接得到
相对地址:相对于当前指令地址的偏移量
(详见上一节↓)
如OP为JMP,地址码为7,此时PC的值将改为7,CPU根据PC的值指向指令7
二.数据寻址
确定本条指令的地址码指明的真实地址(如起始地址为100,OP为JMP,地址码为7,则真实地址为107而不是7)
一地址指令结构(操作码,寻址特征,形式地址A)
①寻址特征表示使用以下的哪种寻址方式
②确定了使用哪种寻址方式,再结合形式地址A,即可得到操作数的真实地址(也称有效地址EA)
二地址指令结构(操作码,寻址特征,形式地址A1,寻址特征,形式地址A2),需要为每个形式地址指明它的寻址特征
以下假设指令字长=机器字长=存储字长,希望找到的操作数是3
1.隐含寻址
不是明显地给出操作数的地址,而是在指令中隐含着操作数的地址。如ACC中的操作数不需要指令指出。
优点:有利于缩短指令字长
缺点:需增加存储操作数或隐含地址的硬件
2.立即(数)寻址
待找的操作数直接被放在指令中,即形式地址A就是操作数本身,又称为立即数,一般采用补码形式。寻址特性为“#”的表示立即寻址。
执行一条指令需要在取指令时访存1次
优点:指令执行阶段不需要访问主存,执行时间最短
缺点:A的位数限制了立即数的范围
3.直接寻址
EA=A,LDA为取数指令
一条指令的执行共需要2次访存:取指令、执行指令
优点:实现简单,指令执行阶段仅访问一次主存,不需专门计算操作数的地址。
缺点:A的位数决定了该指令操作数的寻址范围,操作数的地址不易修改。
4.间接寻址
(1)一次间址
A中存放的是EA,即EA=(A)
一条指令的执行需要3次访存:取指令1次+执行指令2次
(2)两次间址
存储单元第一个比特位是1需要继续寻找,为0表示后面就是EA
共需要4次访存:取指令1次+指令执行3次
可以看出,n次间址的访存次数:1+(n+1)=n+2次
优点:可扩大寻址范围(有效地址EA的位数可以大于形式地址A的位数);便于编制程序(用间接寻址可以方便地完成子程序返回)
缺点:指令在执行阶段要多次访存,多次寻址需根据存储字的最高位确定几次访存
5.寄存器寻址
寄存器中存放操作数。直接给出操作数所在的寄存器编号Ri,即EA=Ri
一条指令的执行需要在取指令时访存1次
优点:指令在执行阶段不访问主存,只访问寄存器;指令字短且执行速度快,支持向量/矩阵运算。
缺点:寄存器价格昂贵,计算机中寄存器个数有限。
6.寄存器间接寻址
寄存器中存放操作数的地址。寄存器Ri指向的是操作数所在主存单元的地址,即EA=(Ri)
一条指令的执行需要2次访存:取指令1次+指令执行1次
特点:比一般间接寻址相比速度快,但指令的执行阶段需要访问主存
7.相对寻址(程序浮动、转移指令)
相对于下一条指令的偏移。取出当前指令后,PC指向下一条指令,再以PC作为起点,EA=(PC)+A
A可以看做是所指地址的偏移量,可正可负,通常用补码表示。
若程序的起始地址为M,OP为JMP的主存地址为M+3,对应地址码为0(指向第一条指令)。执行完JMP后PC指向M+4,为了保证跳转到第一条指令(即M)而不是跳转到主存地址为0的地址,需要将OP为JMP对应的地址码A的值改为-4,利用相对寻址,EA=(PC)+A=M+4+(-4)=M。因此,我们可以随意挪动代码段,A的值-4一定能让程序跳转回第一条指令(M),即这段代码在程序内浮动时不用再更改跳转指令的地址码
为了防止经常挪动代码造成数组元素的存放地址被频繁修改,可以将程序段和数据端分开存放
优点:便于程序浮动(一段代码在程序内部的浮动)、广泛应用于转移指令
8.基址寻址(多道程序)
以程序的起始存放地址作为起点,即EA=(BR)+A
BR叫做基址寄存器,基址寄存器是面向操作系统的,其内容由操作系统或管理程序确定。在程序执行过程中,基址寄存器的内容不变(作为基地址),形式地址可变(作为偏移量)。当采用通用寄存器作为基址寄存器时,可由用户决定哪个寄存器作为基址寄存器,但其内容仍由操作系统确定。
优点:
①可扩大寻址范围:基址寄存器的位数通常大于形式地址A的位数
②用户不必考虑自己的程序存于主存的哪一空间区域,故有利于多道程序设计:主存中可能同时多个程序的数据,每个程序的起始存放位置不同。程序运行前,CPU的基址寄存器都会修改为当前运行程序的起始存放地址,通常存放在PCB中
③便于程序浮动(整段程序在内存中的浮动):程序可以在主存中以任意位置开始存放
也可采用通用寄存器来代替基址寄存器。R0指明基地址存放在哪个寄存器中,此图中EA=(R0)+A
9.变址寻址(循环程序、数组问题)
程序员自己决定从哪里作为起点,即EA=(IX)+A
IX叫做变址寄存器,同样,也可用通用寄存器作为变址寄存器
变址寄存器是面向用户的,变址寄存器的内容可由用户改变(即改变IX),而形式地址A不变。因此可以看成A作为基地址,IX作为偏移量。
[例]
for(int i=0;i<10;i++){
sum+=a[i];
}
通常情况下需要逐个执行
可以使用变址寻址实现for循环进行优化
将立即数0放到ACC、IX中,EA=(IX)的0+A的7=7指向a[0],IX+1对应for循环的i++,作差比较小于0,因此仍满足for循环条件。跳转回主存地址2,EA=(IX)的1+A的7=8指向a[1],和a[0]相加存ACC,以此类推。
可以看出,在数组处理过程中,可设定A为数组的首地址,不断改变变址寄存器Ⅸ的内容,就可以很容易形成数组中任一数据的地址。因此变址寻址特别适合编制循环程序。
若上述程序不是从0号主存地址开始存放的,则需要结合基址寄存器BR的值得到EA,即EA=(BR)+A+(IX)
10.堆栈寻址
操作数存放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。可以设置一组专门的寄存器,每个寄存器存放一个堆栈元素。也可在主存中划出一片区域作为堆栈。
(1)寄存器存放堆栈/硬堆栈
弹栈和压栈都不需要进行访存,成本高,速度快
设栈顶地址最小
将两个栈顶元素依次弹出进行运算在压回栈顶。每弹出一个元素后SP+1;在压回栈时,SP先-1再压回栈顶。
若M表示栈顶单元,寄存器Y用来存放运算结果
出栈:(M)→ACC,(SP)+1→SP
入栈:(SP)-1→SP,(Y)→(M)
(2)在主存中划分区域作为堆栈/软堆栈
弹栈和压栈都需要进行访存,成本低,速度慢。堆栈可用于函数调用时保存当前函数的相关信息
总结
- 什么叫寻址方式?为什么要学习寻址方式?
解:寻址方式是指确定本条指令的数据地址以及下一条将要执行的指令地址的方法,它与硬件结构紧密相关,而且直接影响指令格式和指令功能。寻址方式分为指令寻址和数据寻址。寻找下一条将要执行的指令地址称为指令寻址,寻找操作数的地址称为数据寻址。 - 试比较间接寻址和寄存器间接寻址
间接寻址是相对于直接寻址而言的,指令的地址字段给出的形式地址不是操作数的真正地址,而是操作数有效地址所在的存储单元的地址,也就是操作数地址的地址。可以是一次间接寻址,也可以是多次间接寻址。而寄存器间接寻址是指在寄存器中给出的不是一个操作数,而是操作数所在主存单元的地址。寄存器间接寻址将有效地址放在存放在寄存器中,比间接寻址少了一次访存。 - 试比较基址寻址和变址寻址
基址寻址是将CPU中基址寄存器BR的内容加上指令格式中的形式地址A而形成操作数的有效地址。变址寻址是指有效地址等于指令字中的形式地址A与变址寄存器IX的内容之和。①它们都可以有效地扩大指令寻址范围;②基址寄存器内容通常由系统程序设定,变址寄存器内容通常由用户设定;③基址寻址适用于程序的动态重定位,有利于多道程序设计;变址寻址适用于数组或字符串以及循环程序的处理;④基址寻址时,基准地址由基址寄存器给出,地址的改变反映在位移量形式地址A的取值上;变址寻址时,基准地址由A给出,地址的改变反映在变址值的自动修改上,变址值由变址寄存器IX给出。 - 常见的寻址方式有哪几种?
①指令寻址用于寻找下一条将要执行的指令地址,分为顺序寻址方式和跳跃寻址方式
②数据寻址方式用于寻找操作数的地址,分为隐含寻址、立即(数)寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址、相对寻址、基址寻址、变址寻址、堆栈寻址