指令周期的数据流

上一节给出了四个阶段的名字和顺序,这一节给出每个阶段具体搬了什么、从哪搬到哪。

这是全章命中率最高的一节。 它的题型极其稳定:给出某个时刻某个寄存器的内容,问当前处在哪个阶段;或者反过来,给出阶段问寄存器内容。而全部答案都能从一张表里读出来——关键是这张表要按”这一拍 MAR 里装的是谁的地址”来组织,而不是按微操作序列硬背。

机制

四个阶段的数据流

取指周期

PC → MAR → 地址总线 → 主存
主存 → 数据总线 → MDR → IR
PC + "1" → PC
OP(IR) → CU
  • MAR 装的是指令地址(来自 PC)
  • MDR 装的是指令本身
  • 结束后 IR = 当前指令,PC = 下一条指令地址

间址周期

Ad(IR) → MAR → 地址总线 → 主存
主存 → 数据总线 → MDR
  • MAR 装的是形式地址 (从 IR 的地址字段取出)
  • MDR 装的是有效地址 EA

这一步做的正是 4.2.2 里间接寻址那一行:。“访存一次只为了拿到一个地址”,这就是间接寻址多一次访存的代价所在。

有的教材在末尾多写一步 MDR → Ad(IR),把有效地址回填进 IR 的地址字段,好让执行周期统一从 IR 取地址。这一步是实现细节,加不加都不影响”间址周期结束时 MDR 里是有效地址”这个结论。

疑问点:间址周期结束后,CPU 内寄存器 MDR 中的内容是指令、操作数地址、操作数,还是无法确定

答案是「操作数地址」。

顺着数据流走一遍就够了:间址周期把形式地址 送进 MAR,去主存读回来的是 单元里存的东西。而间接寻址的定义就是” 单元里存的是操作数的地址”——所以读回 MDR 的正是操作数的地址(有效地址 EA)。

三个干扰项各自对应一个阶段,这道题实际上是在考四个阶段的 MDR 内容能不能分清:

选项什么时候 MDR 里是它
A. 指令取指周期结束时
B. 操作数地址间址周期结束时 ← 本题
C. 操作数执行周期中取数完成时
D. 无法确定——

D 之所以不对,是因为间址周期的动作与具体是哪条指令无关。 只要进了间址周期,做的事就是”按形式地址访存取回一个地址”,没有别的可能。(与之相反,执行周期的 MDR 内容确实”无法确定”——它取决于指令类型。)

执行周期

这个阶段没有统一的数据流,因为动作完全取决于指令类型。三种典型:

指令类型数据流
取数 LOADAd(IR) → MAR,M(MAR) → MDR,MDR → ACC
存数 STOREAd(IR) → MAR,ACC → MDR,MDR → M(MAR)
寄存器间运算 ADD R1,R2R1 → ALU 输入,R2 → ALU 输入,ALU → R1(不访存)

“执行周期访不访存要看指令”是本节第二条高频判断。 寄存器型运算指令的执行周期完全不碰 MAR/MDR。

中断周期

0(或 SP-1)→ MAR
PC → MDR → M(MAR)        保存断点
0 → EINT                 关中断
中断服务程序入口地址 → PC
  • MAR 装的是保存断点用的存储单元地址
  • MDR 装的是断点(也就是 PC 的值,即下一条指令的地址)

注意保存的是”下一条指令的地址”而不是”当前指令的地址”——因为 PC 在取指周期就已经自增过了(5.1.3)。这是中断返回能落在正确位置的原因,详见 5.5.3。

一张表读完四个阶段

这张表的组织方式是关键:先看 MAR 里装的是谁的地址,其余全都跟着确定。

阶段MAR 装谁的地址MDR 内容IR 内容PC 内容访存次数
取指指令地址(来自 PC)指令结束时 = 当前指令结束时 = 下一条1
间址形式地址 操作数地址 EA不变(或地址段被回填)不变1
执行操作数地址(若访存)操作数或结果不变不变(转移指令除外)0 或 1
中断保存断点的单元地址断点(PC 的值)不变结束时 = 服务程序入口1

四条推论,直接就是四道选择题的答案:

  1. MDR 里是指令 → 取指周期。 只有取指周期从主存读指令。
  2. PC 的内容被改变 → 取指周期(自增)、执行周期(转移指令)、中断周期(转入口),间址周期从不改 PC。
  3. IR 的内容被改变 → 只有取指周期。
  4. 不访存的阶段只可能是执行周期(寄存器型指令)。

数据流为什么值得单独讲一节

上一节的阶段划分是逻辑的,这一节的数据流是物理的:每一条箭头都对应结构图上一条真实的连线,每一次搬运都需要一组控制信号把沿途的开关打开。

所以这一节是 5.1 的结构图和 5.3 的数据通路题之间的桥。 5.3 的题目会给一张更具体的图,问”为了完成这条指令,写出各拍的微操作”——而答案的骨架就是本节这四组数据流,只是要按题目给的具体连线重写一遍。

反过来也成立:记不住某个阶段的数据流时,回去看结构图上有哪些线可走。 比如”间址周期 MAR 从哪拿地址”——结构图上通向 MAR 的线只有 PC 和 IR 的地址字段两条,取指用了 PC,那间址只能用 IR。

边界

边界辨析:MDR 里是「操作数地址」/「操作数」

  • 间址周期结束:MDR = 操作数地址(还要再访存一次才拿到操作数)
  • 执行周期取数完成:MDR = 操作数

判据一句话:间址周期访存拿回来的是”地址”,执行周期访存拿回来的是”值”。 间接寻址之所以要两次访存,就是这两次的分工不同。

边界辨析:断点 / 当前指令地址

中断周期保存的断点 = PC 的当前值 = 下一条指令的地址,不是被中断那条指令的地址。

原因在取指周期:PC 在取回指令的同时就已自增。所以中断返回后从下一条继续执行,被中断的那条指令已经完整执行完了(这正是”中断在指令边界响应”的含义)。

例外是故障类异常(如缺页),它需要重新执行出错的那条指令,因此保存的断点是当前指令的地址——见 5.5.2。

关联对照:间址周期 / 执行周期的访存

两者都可能访存,但目的不同:

  • 间址周期访存:为了算出地址——它是寻址的一部分
  • 执行周期访存:为了取到数据或写回结果——它是运算的一部分

4.2.2 那张”访存次数”表里,间接寻址记 2 次,就是这两次各记一次。

对照速查

观察到的现象处于哪个阶段
MDR 中是一条指令取指
IR 刚刚被写入取指
MDR 中是一个地址间址
MAR 的内容来自 IR 的地址字段间址(或执行周期取数)
PC 被写入一个不连续的值执行(转移指令)或中断
完全不访存执行(寄存器型指令)
MDR 中是 PC 的旧值中断(保存断点)
指令取指间址执行访存总次数
ADD R1, R2(寄存器寻址)✅❌不访存1
ADD R1, A(直接寻址)✅❌取数 1 次2
ADD R1, @A(间接寻址)✅✅取数 1 次3
LOAD R1, #5(立即寻址)✅❌不访存1

考点

  • 给 MDR / MAR / IR / PC 的内容判断阶段:本节最稳定的题型,靠上面那张四行表。
  • 算某条指令的访存次数:取指 1 次 + 间址(有则 1 次)+ 执行(看寻址方式)。与 4.1.2 的访存次数模板是同一套算法。
  • 写出某阶段的微操作序列:取指周期五步必须能默写;中断周期四步(保断点、关中断、送入口、转移)。
  • 中断保存的是哪个地址:答下一条指令的地址;故障类异常除外。
  • “间址周期结束后 MDR 中是什么”:答操作数的地址。别选”无法确定”。

链接