摘要:本文从数据流视角,剖析CPU执行指令的核心过程:取指、间址、执行。我们将一步步追踪数据如何通过PC、MAR、MDR、IR等寄存器与三大总线协同工作,完成一条指令的使命。


什么是“指令执行过程”

首先,我们需要解释什么是“指令执行过程”——在CPU内部,一条指令从取出,到执行完毕的所有过程,就是“指令执行过程”。

为了更轻松地理解这个概念,我们需要使用计算机工程中强大的工具——“分而治之”,把整个指令执行过程切割成 4 个部分:什么是“指令执行过程”

深入浅出计算机指令执行(一):解析取指、间址与执行阶段的数据流_计算机组成原理

其中,取指阶段又可以再切割为取值分析(为什么我们要把它们两个合起来统称为取指阶段呢?因为需要取值需要访存,相对耗时多。而分析直接在CPU内部完成,相对耗时极少。所以我们把它们两个合并,这样计算会更简单)。

需要注意的是,以上 4 个阶段中,只有取指阶段执行阶段是每一条指令都有的。而其余两个阶段,只在有需要的时候才会有。

后面,我们会详细的介绍在每一个阶段中,数据流(Data Flow)是怎么样的(也就是从数据的角度看,数据会经过哪里。与之对应的是“从控制信号的角度看”,这种方法称之为“控制流”,但本文不涉及)。

取指阶段

取值阶段的目标,是把“指令”从“内存”中拿到“IR(Instrucion Register)”中去。

知道了目标,问题就随之而来:内存中有那么多条指令,我们怎么知道哪一条是我们所需要的?

——PC(Program Counter)中保存的那一条(保存的是地址,我们需要根据这个地址去取出里面的指令)。

所以取指令的第一步就是:PC把肚子里的地址交给MAR。然后MAR通过地址总线交给内存(PC和内存之间,没有专线。而PC唯一可以传出自己肚子里数据的人,就是MAR。而MAR想要和内存沟通,就必须通过中介——地址总线)。

此时我们已经根据 PC 传来的地址,在内存中定位到了我们需要的指令。现在,我们取出这个地址的指令,将其传给 IR。

首先,需要 CU(Control Unit)发出控制信号,要求内存返回数据给 IR。当内存收到控制信号后,开始准备把数据传给 IR。

而就像 PC 需要使用 MAR 和”地址总线“来链接”内存“一样。”内存“想链接 IR 也一样,也需要类似的操作,先通过 ”数据总线“ 把指令交给 MDR,然后由 MDR 交给 IR。

上面步骤完成后,取值操作只需要最后一步就完成了——CU发出控制信号,要求 PC + ”1“(这里的 ”1“ 是指 1 个数据单元的大小),为取下一条指令做好准备。

深入浅出计算机指令执行(一):解析取指、间址与执行阶段的数据流_执行周期_02

由此我们也可以看出来,控制器想和内存交流,就必须通过 3 条总线(内部多总线方式):

地址总线:从 ”控制器“ 传 ”地址“ 给 ”内存“

数据总线:从 ”内存“ 传 ”数据“ 给 ”控制器“

控制总线:从 ”控制器“ 发 ”控制信号“ 给 ”内存“

间址阶段

间址阶段的主要任务是问路(获取操作数的有效地址)。在取指阶段后,IR中拿到了一条 “间接寻址” 指令。这条指令告诉我们:“操作数不在我这里,你去XX地址(我们称为 A)找一个纸条,纸条上写的就是操作数的真实地址”。

所以,我们需要把地址 A 从 IR 肚子里交给 MAR,让它去内存里找到这个地址 A,取出里面的 “纸条”(也就是有效地址 EA),并把这个 “纸条” 带回来,放进 MDR 里。

需要注意的是:这个 “纸条”(有效地址 EA)是交给 MDR 保管的(而不像 ”取值阶段“ 一般,交给 IR ),不会覆盖 IR 肚子里的原始指令。IR必须牢牢记住自己最初的任务是什么。

接下来,执行阶段就可以拿着MDR里的“纸条”(地址EA),去找到真正的操作数了。

执行阶段

执行阶段中,我们需要去取操作数,然后根据 IR 中的指令,去指挥 ALU(Arithmetic Logic Unit)对操作数进行相应的操作。因为不同的指令对应的操作都不相同,所以没有统一的数据流,但万变不离其宗,其核心都是根据 IR 中的指令,由 CU 产生控制信号,指挥 ALU 对操作数进行运算,并将结果送达目标位置(寄存器或内存)。

中断阶段

至此,我们已经详细剖析了指令周期中的取指、间址和执行三个阶段。指令周期还有一个重要的阶段——中断周期,它负责处理来自外部设备的异步请求。

因为在我使用的教材中,这一章被安排到非常靠后的位置,所以目前还没有学到这一部分。等后续学习透彻后,会再写新文章来专门分享中断机制的原理和数据流。


总结

在 CPU 执行指令中,PC 负责报地址,MAR 和 MDR 负责跑腿搬运,IR 牢牢记住要做什么,为控制单元提供执行的依据,ALU 埋头苦干。而地址、数据、控制三条总线则是 ”控制器“ 和 ”内存“ 之间的交流器。