计算机组成原理4.2指令寻址方式

4.2.1指令寻址和数据寻址

4.2.1.1指令寻址:

顺序寻址: 取出指令后PC指向下一条需执行指令的地址

1)顺序寻址:

定长指令字结构寻址:
假设指令字长 = 存储字长 = 16bit = 2Byte,且主存按字编址。则每次取出指令后PC + 1;若主存按字节编址,意味着每条指令都会占两个地址,则每次取出指令后PC + 2。
在这里插入图片描述
在这里插入图片描述变长指令字结构寻址:指令字长 = 存储字长 = 16bit,主存按字节编址。假设相同颜色的是同一条指令。
在这里插入图片描述
假设从0开始,CPU无法判断指令长度,因此CPU会每次先读入一个字,并区分按字节编址还是按字编址,使得程序计数器PC + “一个指令长度”,本次叙述的是按字节编址,因此PC + 4,若按字编址,PC + 2。操作码被包含在第一个字,CPU根据操作码判断读取指令是几地址指令,由此确定指令占用多少字节,并继续读取后续。

2)跳跃寻址:

下一条指令的地址码不由程序计数器指出,而是由本条指令给出下条指令地址码的计算方式。
定长指令字结构寻址,指令字长 = 存储字长 = 16bit,主存按字编址。意味着每条指令占用一个字,两个字节;变长指令字结构寻址,与顺序寻址中变长指令字结构的情况可类比,不一一赘述,主存按字节编址的情况与顺序须知可以类比得出,也不赘述。
在这里插入图片描述
如上图,仍然假设CPU从0开始读入指令,从0~2都是顺序寻址,此时,执行完指令2时,PC指向的是指令3,接下来,CPU读入指令3,PC + 1,PC指向4,CPU执行指令3,指令3是JMP,无条件跳转指令,跳转到7,此时PC重新指向,指向7。

4.2.1.2 数据寻址:

确定本条指令的地址码指向的真实地址,是指如何在指令中表示一操作数的地址,与跳跃寻址并不相同。由于数据寻址的方式较多,为了便于区别,会在指令字的形式地址前面设置几个bit作为寻址方式位,这几位是寻址特征。每个形式地址前面都会有一个寻址方式位。

4.2.2 数据寻址的方式

一地址指令:
在这里插入图片描述
二地址指令:
在这里插入图片描述
介绍十种数据寻址方式,由于10 < 16 = 24,因此十种情况用4个bit表示足以。假设指令字长 = 机器字长 = 存储字长,假设操作数是3。

4.2.2.1 直接寻址

在这里插入图片描述
指令字中的形式地址A就是操作数3的真实地址EA,CPU根据形式地址去主存中相应地址找到数据3并将其放入ACC中进行计算。取指令,执行指令一共访问主存两次直接寻址过程简单,但操作数的地址范围有限,且操作数地址发生变化时指令需要再修改。

4.2.2.2 间接寻址

在这里插入图片描述
指令的形式地址码A指向主存中某个有效地址EA,EA中存储着操作数的真实地址,可以用EA = (A)来表示,其中(A)表示地址A所指向的主存单元里的数据取指令访问存储一次,执行指令访问存储两次一共三次。间接寻址扩大了寻址范围,便于编写汇编程序,但是由于需要多次访存,因此执行指令速度会慢。 间接寻址可以多层“套娃”,间接寻址可以与C语言中的一级指针、二级指针、多级指针类比理解。

4.2.2.3 寄存器寻址

在这里插入图片描述
指令中的形式地址码Ri指向某个编号为Ri的寄存器寄存器中存放操作数,取指令访存一次,执行指令不需要访存寄存器寻址执行指令不需要访存,因此执行速度快,支持向量或者矩阵运算,但由于价格昂贵,寄存器个数有限。

4.2.2.4 寄存器间接寻址

在这里插入图片描述
指令中Ri指向某个编号为Ri的寄存器,寄存器中存放操作数在主存中的真实地址EA,EA = (RI),取指令访存一次,执行指令访存一次共两次。寄存器间接寻址比一般间接寻址更快。

4.2.2.5 隐含寻址

在这里插入图片描述
如两个操作数的运算,一个操作数的地址存放在指令的形式地址码A中,另一个操作数B在ACC中,操作数B被指令隐含在ACC中。缩短了指令长度,但需要增加存储操作数或者隐含操作数地址的硬件。

4.2.2.6 立即寻址

指令的形式地址码就是操作数本身,一般用补码表示,#表示立即寻址特征取指令访存一次,执行指令不访存,指令执行时间短,但形式地址码的位数限制了操作数的表示范围

4.2.2.7 基址寻址在这里插入图片描述指令中形式地址码A加上基址寄存器中的内容就是操作数的有效地之EA,EA = (BR) + A,如上图,CPU中的基址寄存器可以,可以采用专用的寄存器,也可以采用通用寄存器,但是若采用通用寄存器,需要在指令中用若干bit表示为Ri,来指明使用了编号Ri的通用寄存器作为基址寄存器。
关于基址寻址过程:

在这里插入图片描述
还是采用讲义里的笔记截图,假设这一段程序的指令,在主存中的地址不是从0开始,而是从100或者其他地址开始。程序运行前,CPU将BR的值修改为当前要执行程序的起始地址,存放到操作系统的程序控制块PCB中。PC指向程序指令起始地址100,第一条指令是取出操作数a,a存放在主存地址码为105 = 100 + 5的位置。基址寻址适用于多道程序设计,可扩大寻址范围,可用于编写经常浮动的程序。

4.2.2.8 变址寻址在这里插入图片描述

指令中形式地址码A加上基址寄存器中的内容就是操作数的有效地之EA,EA = (IX) + A,如上图,CPU中的基址寄存器可以,可以采用专用的寄存器,也可以采用通用寄存器,但是若采用通用寄存器,需要在指令中用若干bit表示为Ri,来指明使用了编号Ri的通用寄存器作为基址寄存器。

关于变址寻址过程:

假设要执行一段程序

for(int i = 0, i < 10; i ++)
{
	sum = sum + a[i];
}

在这里插入图片描述
PC指向第二条指令,PC + 1,取操作数到IX中,此时IX为0,下一条指令的形式地址指向7,则ACC中的操作数0,与 7 + (IX) 得到的地址中的数据相加再放到ACC中,完成一次数组元素加法操作,执行指令IX + 1,则是for循环中的i++,比较IX中的数据与10,则是执行判断i < 10。执行指令5,满足指令中的条件,跳转到指令2,重复前述步骤。后续指令执行较为简单,不再赘述。变址寻址适用于循环程序

4.2.2.9 相对寻址在这里插入图片描述

指令中的形式地址码A加上PC中的内容形成的有效地址码EA,EA = (PC) + A,A是相对于PC的偏移量,可正可负,用补码表示。
在这里插入图片描述

仍然是讲义中的例子,假设把for循环移动到其他位置,此时就需要用相对寻址,假设for循环程序的起始地址是M,则执行指令到M + 3时,PC + 1 = M + 4,此时(PC) + A,得到M,完成一次循环。相对寻址使得for循环有关程序可以在整个程序内任意浮动,而不用修改指令中的形式地址。

4.2.2.10 堆栈寻址

操作数放在堆栈中,使用堆栈指针(Stack Pointer,SP)作为操作数有效地址,按照FIFO先进先出的原则管理堆栈存储器。可分为硬堆栈和软堆栈,硬堆栈是寄存器堆栈,在CPU中用指定寄存器来存放堆栈,不需要访存就能完成寻址从主存中划分出一段存储空间来作为堆栈的是软堆栈,软堆栈需要一次访存
假设用4个寄存器实现堆栈,CPU从堆栈区按顺序,取出栈顶元素放到ACC中,SP + 1,指向次栈顶元素,取出次栈顶元素放到X中。计算完毕,把计算结果压入栈,SP - 1,完成一次加法操作,减法操作亦然。如下图。在这里插入图片描述
有些情况下栈顶的位置可能在地址数值较小的位置,也可能在地址数值较大的位置,需要详细区分。
计算上述加法过程中,硬堆栈不访存,软堆栈每次压入栈或者弹出栈的操作,都需要访存。
关于堆栈寄存器,在后续的CPU基本结构中也会涉及到。
在这里插入图片描述

posted @ 2021-05-27 12:42  桃浪十七  阅读(2248)  评论(0编辑  收藏  举报