4.2.1指令寻址

本文详细解释了计算机中的指令寻址机制,包括顺序寻址(通过程序计数器自动加一确定地址)和跳跃寻址(如无条件转移指令改变执行流),重点讨论了不同编址方式和指令结构对寻址的影响。
摘要由CSDN通过智能技术生成

前言

在这里插入图片描述

各位同学大家好,经过之前几个小节的学习,我们已经知道了指令在计算机内部是如何表示的,在逻辑上,一条指令可以被分为操作码和地址码这样的两大部分,其中地址码有可能会有多个,我们用高级语言写的程序,最终一定会被转换为用机器语言表示的一条一条的指令,而这些指令序列在储存当中被顺序的存放,那之前我们说过在一个计算机当中,有可能各条指令的长度是不一样的。
在这里插入图片描述

那么计算机在执行这些指令序列的时候,是如何确定下一条指令的存放地址的呢?这就是这个小节要探讨的所谓指令寻址的问题。

顺序寻址

cpu可以通过顺序寻址或者跳跃寻址这样的两种方式,来确定下一条指令在主存当中的存放位置。
在这里插入图片描述

首先,我们还是来回顾一下之前我们提到过很多次的这个例子,我们用高级语言编写的这段程序被翻译成与之等价的一系列机器指令,这些机器指令和各种变量这一类的数据被无差别的存放在储存当中,那cpu内部会有一个很重要的寄存器,叫做程序计数器programcounter(PC),用程序计数器来表明接下来应该执行的是哪一条指令,那刚开始pc这个程序计数器会被指向我们这个程序的第一条指令,在这个例子当中,这条指令是存放在主存地址为零的这个地方。
在这里插入图片描述

那接下来cpu取得这条指令之后,会让pc这个程序计数器的值自动的加一也就是指向下一条应该执行的程序,用这样的方式可以把这些指令一条一条的往后顺序的执行,所以正常情况下,cpu确定下一条指令的存放地址的方式很简单,就只需要让pc程序计数器的值加一就可以,因为正常情况下,这些指令都是顺序执行的。

在这个例子当中,大家会发现我们给主存的这些存储单元编址的时候,是按存储字,按字编址的,我们每个存储字可以存放两个字节的数据,所有的这些指令也刚好都是占两个字节,所以这个例子比较特殊的是,我们只需要简单的让pc不断的加一就可以找到下一条指令存放的这个存储字,那我们要注意一些情况导致无法加一顺序执行:
(1)第一种情况:按字节编址
如果这个主存是按字节编址的话,那么就意味着每一条指令会占两个地址,那这样的话,我们每一次让pc简单的加一就不行了,需要加二,这就是第一种我们值得考虑的情况。

(2)第二种情况:采用变长指令字结构
如果说这系统当中它采用变长指令字结构,那我们寻找下一条指令的存储地址会变得很复杂,程序计数器pc的值简单的加一肯定就不行。
在这里插入图片描述

所以对于指令寻址这个问题,并不是让pc简单的加一就可以,不过我们可以确定的是,pc程序计数器,它始终都是指向了下一条我们应该执行的指令存放的地址。
在这里插入图片描述

我们一条一条的机器指令在内存当中被顺序的存放,那大家可以数一下,这儿的每一行总共是16个比特,两个字节。
在这里插入图片描述

那我们假设这样的一行刚好就是一个存储字,然后在这个系统当中,我们采用定长指令字结构,并且指令字长刚好等于存储字长,也就是等于两个字节,另外,我们还规定这个主存是按字编址的,那这样的话,两条指令他们之间的地址相差刚好就是一,也就我们刚才所说的最简单的那种情况,这样的话,cpu每取走一条指令之后,只需要简单的让pc程序计数器的值加一指向下条指令就可以。
在这里插入图片描述

那这地方我们是用机器语言二进制来表示的指令,我们可以把它换作比较好看的这个汇编语言的形式,每一条会编语言指令和机器指令是一一对应的,同样有操作码,也会有地址码,每一条指令是占一个存储字,而我们模拟一下这段程序的一个执行过程:
在这里插入图片描述

刚开始,pc的值会指向这段程序的第一条指令,那第一条指令存放在零这个地址,那由于指令字长和存储字长都是两个字节,所以cpu只需要根据pc所指向的这个地址,取出这一整个存储字的内容,那这个内容就是第一个指令。
在这里插入图片描述

当这条指令被取出之后,pc的指会自动加一指向下一条应该执行的指令,好,那上面这条指令执行结束之后,接下来cpu又会根据pc所指向的这个位置又取出下一条指令,然后继续让pc加一,所以这就是这一系列的指令顺序执行的一个过程。
在这里插入图片描述

那接下我们把设定的这几个条件稍微改一下,假设这系统当中同样是采用了定长指令字结构,每一条指令的长度都和存储字长一样,都是两个字节,也就是刚好对应这样的一行,每一行就是一个指令,那现在我们改一下,如果说主存是按字节编址,那是不是意味着每一条指令会占两个地址,第一条指令的前八个比特对应字节地址是0。后八个比特对应字节地址是1,然后,第二条指令的前八个比特对应的字节地址是2, 后八个比特对应的字节地址应该是3。
在这里插入图片描述

所以这样的话,我们每一条指令,它存储的一个起始地址,也就是这个字地址,应该是0,2,4,6,每次加二这样的一个规律,所以如果改成这样的条件,那么我们的cpu每取一条指令之后,应该是让pc的值加二,刚开始pc是指向零那么取走这一整个字之后,接下应该执行的指令,它存放的地址应该是二,所以我们应该让pc的值加二。

因此,如果主存的这个编址方式发生了改变,那么我们对pc的处理也会相应的发生改变。

到目前为止,我们看的是定长指令字结构,也就是每一条指令的长度都是确定不变的,接下我们再看一下,如果说这个系统是采用了变长指令字结构,同时也是按照字节编址,那这种情况下pc的值又应该怎么变化呢?
在这里插入图片描述

那在这个图示当中,我们会给相邻的几个存储字,给他们涂上相同的颜色,那么具有相同颜色的存储字就表示说这几个存储字共同组成了一条指令,那这种情况下,不同的指令它的指令字长是不一样的,就不再是固定为二B两个字节这么简单.
在这里插入图片描述

我们来分析一下这些指令的执行过程,刚开始,pc的值肯定是指向零指向第一条指令的这个存储地址,那么,由于cpu无法确定当前指向的这条指令到底占几个存储字,那这种情况下,cpu可以首先读入第一个字的内容,那么由于操作码被包含在了第一个字里面,所以,cpu可以根据这里边隐含的操作码来判断出这一条指令到底是几地址的指令,这样就可以确定这条指令它总共占多少个字节.
在这里插入图片描述

好,那对于这个例子来说,cpu现在可以确定这一条指令总共占四个字节,也就是两个存储字,因此,接下来cpu还会紧接着取入后面的两个字节,这样就得到了完整的一条指令,那么,在取指令这个阶段结束之后,cpu会把pc的值加上n,这的n指的是我们刚才取出的这条指令的总字节数,因为我们是按字节编址的,所以需要加上总字节数,那这样的操作就导致了pc程序计数器的值指向了四这个地址,也就指向了下条指令的存放地址,这就是采用变长指令字结构按字节编指的一个处理方式。
在这里插入图片描述

由于无法预先判断当前要执行的这条指令指令字长到底是多长,因此,cpu都会先读入一个字,然后接下来根据指令的类型,有可能还要进行多次访存,也就是读入一条指令后续那几个字,比如说,对于这灰色的这一条指令,他总共占三个存储字,那这条指令cpu就需要进行三次访存才可以把它完整的读出。

目前为止我们介绍的指令寻址方式都可以统一的归为顺序寻址,因为到目前为止,我们介绍的例子都是一条一条往后顺序的执行各个指令,每次会让pc的值加“n”,这儿的n我们应该把它理解为是当前取出的这条指令的指令字长,那结合当前执行的这条指令的指令字长,再结合上系统到底是采用按字编址还是按字节编址,结合这些信息来判断pc这一次应该加多少。

所以在今后的讲解中,我们依然会描述为取走一条指令之后让pc加“1”,但是大家需要知道我们这所谓的加一是双引号的一,实际上有可能是其他的值好,以上就是顺序寻址方式的介绍。(也就是一条一条顺序的往下执行各个指令)

跳跃寻址

接下我们再介绍第二种指令寻址方式,叫做跳跃寻址。
在这里插入图片描述
跳跃寻址可以根据转移类的指令来指出接下来应该执行的指令在什么位置,我们还是结合刚才使用的这个例子来继续往下分析,同样,我们规定系统采用定长指令字结构,每一个指令字的字长和存储字长是相同的,都是占两个字节,并且这系统采用按字编址
在这里插入图片描述

所以pc刚开始指向第一条指令,也就是零这个地址所存放的指令,那cpu取出这条指令之后,会让pc的指自动加1,
在这里插入图片描述

也就指向下一条应该执行的指令所存放的地址,那需要注意的是,pc指向的是下一个应该被执行的指令所存放的地址(1),并不是当前执行的这条指令的地址(0),对于刚才这个场景来说,cpu此时正在执行的应该是零这条指令,那么,当这条指令执行结束之后,cpu才会根据pc所指向的位置去取走下一条指令,同时执行这条指令,另外也需要让pc的指继续加一指向下条指令。总之就是每取走一条指令,就让pc加一,同时cpu执行当前这条指令,那前面的这三条指令只是进行简单的算数运算,或者就是取一个数,这样的操作并不会改变整个程序的执行流,但是对于三这个地址所存放的指令就不一样了。

在这里插入图片描述

当cpu执行到三所存放的这条指令的时候,首先,第一点cpu取出这条指令之后,同样会让pc的指加一也就是指向四这条指令,但是,cpu执行这条指令的过程中发现,这条指令它是一条无条件转移指令jump,JMP指的是jump,就是跳转的意思,那jump后面表示的这个地址七,意味着下一条应该执行的指令存放在什么位置,类似于c语言里的GOTO语句.
在这里插入图片描述

所以执行这条指令的效果就是会让pc的值强行的变为7这个值,那接下来执行了这条指令之后,cpu是不是就会根据pc所指向的这个位置(7),去取出下一条应该执行的指令,因此,jump这条指令改变了程序的执行流,通过这种转移指令让cpu跳跃着找到了下一条指令的存放位置。

所以我们前边每一次pc加一这种指令寻址方式就是顺序寻址,而通过转移类的指令改变了程序的执行流,也就直接改变了pc的值,这种指令寻址方式就是跳跃寻址。

总结

在这里插入图片描述

这个小节当中,我们介绍了两种指令寻址方式,所谓指令寻址就是说我们需要确定下一条需要执行的指令的存放位置,那这个存放地址是由程序计数器pc来指明的,pc指向哪个地址就意味着接下来要执行的指令存放在什么地址,通常来说,pc会有自动加一的功能,每一次cpu取走一条指令之后,取指阶段结束,pc的值都会自动的加一。只不过这地方的一我们要理解为是一个指令字长,具体加多少,我们需要具体情况具体分析。

取指令完成之后,cpu就会执行这条指令,执行完当前这条指令之后,cpu就会根据pc所指向的位置去找到下一条指令所存放的地址,有的时候,cpu可能会执行到转移类的指令,比如说刚才提到的无条件转移指令jump,还有就是函数调用的指令call,这些指令都会改变程序的执行流,或者从另一个角度来讲,就是会直接修改pc的值,这样的话,就会导致程序的执行流不再是顺序的往后执行,而是会跳跃到另一个地方来执行,所以通过这种方式找到下一条指令的存放地址,我们把它称为跳跃寻址。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值