跳到正文
IGCSE·Tuition
计算机科学 · 课程

追踪简化的指令周期

fetch、decode、execute 这几个词谁都背得出,直到题目问每一步之后各寄存器的值。

本页内容
  1. 每个阶段发生什么?
  2. 例题详解
  3. 要留意的错误
  4. 自我检测
  5. 下一步

处理器通过重复一个周期来运行程序:从内存取出(fetch)下一条指令,解码(decode)它,然后执行(execute)它。追踪这个周期,就能看到每一步之后各寄存器存着什么。

这项技能属于硬件与处理。它是下一课每个寄存器的作用的基础,也与算法题里的追踪表密切相关。

每个阶段发生什么?

我们使用有五个寄存器的简化模型:程序计数器(PC)、内存地址寄存器(MAR)、内存数据寄存器(MDR)、当前指令寄存器(CIR)和累加器(ACC)。

Fetch

  1. PC 中的地址被复制到 MAR。
  2. PC 加 1,指向下一条指令。
  3. MAR 所指内存位置的内容被复制到 MDR。
  4. MDR 的内容被复制到 CIR。

Decode。 控制单元(control unit)弄清 CIR 中指令的意思:做什么操作,用哪个地址。

Execute。 执行指令。加载(load)把一个值复制到 ACC,算术指令使用算术逻辑单元(ALU)并把结果留在 ACC,存储(store)则把 ACC 复制到内存。

用伪代码写,fetch 如下:

MAR ← PC
PC ← PC + 1
MDR ← Memory[MAR]
CIR ← MDR

例题详解

内存中有下面的程序和数据。LDA 200 把地址 200 的值加载到 ACC,ADD 201 把地址 201 的值加到 ACC,STO 202 把 ACC 存到地址 202,END 表示停止。

地址内容
100LDA 200
101ADD 201
102STO 202
103END
2007
2015
2020

PC 从 100 开始。ACC 一开始是空的,用短横线表示。

步骤PCMARMDRCIRACC
开始100----
Fetch 1101100LDA 200LDA 200-
Execute 11012007LDA 2007
Fetch 2102101ADD 201ADD 2017
Execute 21022015ADD 20112
Fetch 3103102STO 202STO 20212
Execute 310320212STO 20212
Fetch 4104103ENDEND12

关键数值要核对两次。Execute 2 中,ALU 计算 7 + 5 = 12。Execute 3 中,12 被写入地址 202,所以位置 202 从 0 变成 12。

每次 fetch 读取的是 PC 增加之前的地址:100、101、102、103。

同一个周期用 Python 写出来,用字典(dictionary)当作内存:

memory = {100: "LDA 200", 101: "ADD 201", 102: "STO 202", 103: "END",
          200: 7, 201: 5, 202: 0}
pc = 100
acc = 0
while True:
    mar = pc
    pc = pc + 1
    mdr = memory[mar]
    cir = mdr
    op = cir.split()[0]
    if op == "END":
        break
    address = int(cir.split()[1])
    if op == "LDA":
        acc = memory[address]
    elif op == "ADD":
        acc = acc + memory[address]
    elif op == "STO":
        memory[address] = acc
print(memory[202])   # 12

这是教学模型,不是真实处理器的构造方式,你可以用安全的 Python 推理沙盒运行这样的小例子。

要留意的错误

常见的失误是在 execute 阶段之后才更新 PC,或让 PC 停在正在运行的指令的地址上。

错误的 Fetch 1 行: PC 100,MAR 100,MDR LDA 200,CIR LDA 200

学生让 PC 停在 100,因为“指令就在那里”。

PC 在 fetch 期间就加 1,所以 Fetch 1 之后它已经是 101。这个错误会扩散:之后每个 MAR 都差一,整个追踪就全错了。改正的办法是把“PC 加 1”写成每次 fetch 的第二行。

自我检测

1. 一次 fetch 开始时 PC 是 300。写出 fetch 前两步之后 MAR 和 PC 的值。

查看答案

第 1 步把 PC 复制到 MAR,所以 MAR = 300。第 2 步把 PC 加 1,所以 PC = 301。

2. 控制单元解码指令时,指令存放在哪个寄存器?

查看答案

CIR(当前指令寄存器)。MDR 只在指令从内存传来的途中暂时存放它。

3. 指令 JMP 150 存放在地址 120。写出它 fetch 之后和 execute 之后的 PC。

查看答案

fetch 之后 PC = 121。执行跳转会用新地址覆盖 PC,所以 execute 之后 PC = 150。下一次 fetch 使用 MAR = 150。

下一步

会追踪这个周期之后,请把每个寄存器与其作用对应起来,再试硬件与处理练习题。受限伪代码追踪训练器适合培养同样的逐步追踪数值的习惯。

有些学生在课堂上能跟上追踪,一个人面对空白纸时却理不出头绪。线上一对一计算机科学补习的老师可以陪你一个寄存器一个寄存器地追踪,直到这个规律稳固下来。

常见问题

fetch 期间 PC、MAR、MDR 和 CIR 按什么顺序变化?

在简化模型中:先把 PC 中的地址复制到 MAR,再把 PC 加 1,然后把该地址的指令复制到 MDR,最后复制到 CIR。务必在 fetch 阶段就写出 PC 前进,而不是等到指令执行之后。

为什么 PC 存的不是正在执行的那条指令的地址?

因为 PC 在 fetch 期间已经更新,指向下一条指令。当前指令执行时,PC 存的是下一个地址。跳转(jump)指令则不同:它会用新地址覆盖 PC,所以下一次 fetch 会发生在别的地方。

这一课需要学真实的汇编语言吗?

不需要。题目会给出所用的少量指令,或者用文字描述。你的任务是一致地应用这个周期,并写出每个寄存器的值。请到 Cambridge 官网科目页面查看当前考纲对这个课题的表述,作答时使用题目给出的指令名称。

资料来源

  1. Cambridge IGCSE Computer Science 0478 科目页面

更新于:

下一步

如果你的追踪表总是错一行或错一个寄存器,一对一的老师可以看着你现场追踪程序,找出数值开始出错的那一步。

一小时付费试听课,按所安排老师确认的收费,RM80 起。 其他费用、时间安排及后续课程,在试听课后由家长与老师直接确认。

补习由家长或监护人安排。用 WhatsApp 把这页发给他们,他们就可以替你咨询。

是家长或监护人?在这里咨询

已通过我们的服务帮助 9,000+ 名学生