Appearance
一条指令在CPU里的一生——模拟器使用指南
考情分析
指令执行的五个阶段(IF→ID→EX→MEM→WB)和控制信号是 408 的高频考点。很多同学能画出数据通路图、能列出控制信号表,但合在一起就迷糊——"这条指令到底走了哪些部件?哪些信号在起作用?"
这个模拟器让你跟着一条指令"走一遍" CPU,每一步都能看到哪些部件被点亮、哪些信号被激活:
| 考点 | 你会在哪个场景看到 | 考频 |
|---|---|---|
| 指令执行五阶段(IF/ID/EX/MEM/WB) | 跟着指令走 | 🔥🔥🔥 |
| 控制信号(ALUSrc/RegWrite/MemToReg/...) | 跟着指令走 | 🔥🔥🔥 |
| R 型 vs I 型指令的数据通路差异 | 换条指令试试 | 🔥🔥🔥 |
| 数据通路部件功能 | 认识 CPU | 🔥🔥 |
按顺序走完三个场景大约 15 分钟。走完之后再看数据通路的大题,脑子里有画面会清楚很多。
场景一:认识 CPU
打开模拟器后默认进入这个场景。你看到的是一个简化的单周期数据通路图——所有部件灰色,等你点击。
你应该点击的七个部件
1. PC(程序计数器)
点击后弹出说明:"我记住下一条指令的地址。每执行一条,自动 +4。" PC 自增是硬件自动完成的,不需要控制信号。
2. 指令存储器(IM)
存放所有指令。PC 给地址,IM 返回对应的 32 位指令编码。
哈佛结构
指令存储器和数据存储器分开——这就是"哈佛结构"的思想。分开的好处是取指和访存可以同时进行(流水线需要这一点)。
3. 控制器
指挥官。根据 opcode(和 funct)生成所有控制信号。控制信号在译码阶段就全部确定,但各信号在不同阶段才起作用。
4. 寄存器堆
32 个寄存器($0-$31),可同时读两个(rs、rt 端口)、写一个。$0 永远为 0。
5. ALU
做加减与或比较等运算。输出运算结果 + Zero 标志(结果为 0 时 Zero=1)。
6. 数据存储器(DM)
主存。lw 从这里读数据,sw 往这里写数据。R 型指令不用它。
7. MUX(多路选择器)
数据通路上有两个关键 MUX:
- ALU 输入 MUX:ALUSrc 控制,=0 选寄存器,=1 选立即数
- 写回 MUX:MemToReg 控制,=0 选 ALU 结果,=1 选内存值
右侧信息面板
始终显示当前指令的:
- 汇编格式和二进制编码
- 指令字段分解(op/rs/rt/rd/shamt/funct 或 op/rs/rt/imm)
- 关键寄存器的当前值
场景二:跟着一条指令走
点击"跟着指令走"标签,进入核心场景。默认指令是 add $t0, $t1, $t2($t1=5, $t2=3)。
动画的五个阶段
每一步都可以暂停(⏸)、单步推进(▶)、回退(◀):
阶段 ① 取指(IF)
| 你能看到什么 | 对应考点 |
|---|---|
| PC 高亮 → 地址流向指令存储器 → 指令编码取出 | 取指过程 |
| +4 加法器高亮 → PC 更新为 PC+4 | PC 自增 |
408 常考
取指阶段做两件事:①取指令 ②PC+4。这两件事是硬件自动完成的,所有指令都一样,不需要控制信号参与。
阶段 ② 译码(ID)
| 你能看到什么 | 对应考点 |
|---|---|
| 指令编码拆成 6 个字段,每个字段不同颜色 | 指令格式 |
| opcode 送入控制器 → 控制信号逐个亮起(绿=1,红=0) | 控制信号生成 |
| rs/rt 字段送入寄存器堆 → 读出 $t1=5, $t2=3 | 寄存器读取 |
记忆要点
控制器在译码阶段就一次性生成所有控制信号。比如 RegWrite=1 虽然在 ID 就确定了,但它在 WB 阶段才真正控制寄存器堆写入。
阶段 ③ 执行(EX)
| 你能看到什么 | 对应考点 |
|---|---|
| ALUSrc MUX 高亮 → ALUSrc=0 → 选寄存器值 | ALU 输入选择 |
| 两个操作数(5, 3)进入 ALU → 输出 ALU Result=8 | ALU 运算 |
| Zero 信号输出(8≠0 → Zero=0) | Zero 标志 |
易混
R 型指令 ALUSrc=0(两个输入都来自寄存器)。lw/sw 的 ALUSrc=1(第二个输入是立即数)。但 beq 虽然是 I 型,ALUSrc=0(做寄存器比较,不用立即数做 ALU 运算)。
阶段 ④ 访存(MEM)
| 你能看到什么 | 对应考点 |
|---|---|
| 数据存储器保持灰色 → MemRead=0, MemWrite=0 | add 不访存 |
| ALU 结果直接穿过 | 只有 lw/sw 用数据存储器 |
WARNING
add 不需要数据存储器,但阶段不能跳过——硬件是固定连线的,只是控制信号让数据存储器"什么都不做"。这个理解对后面学流水线非常重要。
阶段 ⑤ 写回(WB)
| 你能看到什么 | 对应考点 |
|---|---|
| MemToReg MUX 高亮 → MemToReg=0 → 选 ALU 结果 | 写回数据来源 |
| 结果 8 写回寄存器堆 → $t0 从 0 变为 8 | RegWrite=1 |
完成后出现绿色汇总面板,列出五个阶段的关键动作和信号。
场景三:换条指令试试
这是最有价值的场景。从下拉菜单选择不同指令,看它走的路径和 add 有什么不同。
三条可选指令
| 指令 | 和 add 的关键差异 |
|---|---|
lw $t0, 0($t1) | ALUSrc=1(用立即数算地址),MemRead=1(要访存),MemToReg=1(写回内存值) |
sw $t0, 0($t1) | MemWrite=1(写内存),RegWrite=0(没有写回阶段) |
beq $t1, $t2, +4 | ALU 做减法比较,Branch=1,Zero=1 时 PC 跳转,RegWrite=0(没有写回) |
对比表(核心考点)
右侧面板会自动展示和 add 的控制信号对比表。差异项高亮显示:
| 信号 | add | lw | sw | beq |
|---|---|---|---|---|
| ALUSrc | 0 | 1 | 1 | 0 |
| MemRead | 0 | 1 | 0 | 0 |
| MemWrite | 0 | 0 | 1 | 0 |
| RegWrite | 1 | 1 | 0 | 0 |
| MemToReg | 0 | 1 | × | × |
| Branch | 0 | 0 | 0 | 1 |
| RegDst | 1 | 0 | × | × |
记忆技巧
只需要记住 add 的控制信号(全部都是"默认值"),然后记住每种指令和 add 哪里不一样:
- lw:ALUSrc、MemRead、MemToReg 变 1,RegDst 变 0(写 rt 不是 rd)
- sw:ALUSrc 变 1,MemWrite 变 1,RegWrite 变 0(不写回)
- beq:Branch 变 1,RegWrite 变 0,ALU 做减法
考研高频考点速览
| 考点 | 考频 | 关键记忆 |
|---|---|---|
| 指令执行五阶段 | 🔥🔥🔥 | IF→ID→EX→MEM→WB,每个阶段不能跳过 |
| 控制信号表 | 🔥🔥🔥 | 记 add 的默认值 + 每种指令的差异 |
| ALUSrc 的含义 | 🔥🔥🔥 | =0 选寄存器,=1 选立即数(beq 是例外) |
| MemToReg 的含义 | 🔥🔥 | =0 选 ALU 结果,=1 选内存数据 |
| RegDst 的含义 | 🔥🔥 | =1 写 rd(R型),=0 写 rt(I型) |
| Zero 标志和分支 | 🔥🔥 | Branch=1 且 Zero=1 时 PC 跳转 |
推荐使用流程
第一轮:建立直觉(5 分钟)
- 认识 CPU:点击每个部件,搞清楚它的功能
- 跟着 add 指令走:0.5x 慢速看完五个阶段
- 展开每个阶段的"考点提示",画面 + 文字对照记忆
第二轮:对比差异(10 分钟)
- 切到"换条指令试试"
- 依次选 lw → sw → beq,看每条指令的数据通路
- 重点看右侧对比表:哪些信号不同?为什么不同?
- 自己试着默写四种指令的控制信号表,然后用模拟器验证
第三轮:做题验证(按需)
- 找一道"画数据通路 + 填控制信号"的真题
- 先手画数据通路,标出激活部件
- 用模拟器的动画对照,看自己画对了没有