CPU 与指令系统

从指令语义连接汇编、数据通路和控制器,分类讲解编码、寻址、控制信号与流水线题。

CPU 与指令系统连接着程序和硬件:指令系统规定一条指令要完成什么,数据通路和控制器决定它怎样完成。综合题有时给汇编清单,让你还原程序行为;有时给结构图,让你补数据流、控制信号和时序。两类题都需要先读懂指令语义。

这个板块包含哪些知识

CPU 与指令系统图谱把内容分为软件可见的指令系统、CPU 内部实现和流水线三部分:

  • 指令系统:操作码、指令格式、寄存器字段、立即数、寻址方式、转移目标与机器码。
  • 程序的机器级表示:数组地址、条件与循环、函数调用、栈帧、端序和对齐。
  • 数据通路与控制器:PC、IR、寄存器组、ALU、访存接口、内部总线、多路选择器和控制信号。
  • 指令执行与性能:指令周期、时钟周期、CPI、流水线阶段及结构、数据、控制冒险。

它们的关系可以沿一条指令来理解:解释字段 → 确定操作数与结果 → 找到数据经过的部件 → 安排各拍控制 → 计算执行代价。汇编题偏重前两段,结构图题偏重中间两段,性能题还要考虑多条指令的重叠与停顿。

常见考点与题型

综合题可能组合下面几类小问。先看要求求什么,再确定需要调用哪些知识。

题型题干中的线索解题思路
指令编码与寻址指令格式、寄存器数、地址字段先写指令语义,再分配位数;有效地址与操作数分别计算
汇编与 C 程序对应代码清单、变量、数组或函数逐条标注读写对象,追踪寄存器和内存;分支基准按 ISA 定义
数据通路与位宽结构图、总线、MAR / MDR、MUX沿源到目的追踪数据,结合地址范围与一次传输宽度判断位数
微操作与控制信号节拍、RTL、控制端取值一拍写一组可同时执行的微操作,再从图中读出使能与选择信号
性能与流水线主频、CPI、阶段延时、相关指令单条按周期累计;流水线画时空表,标出依赖、转发和停顿

解题前要弄清的关系

从一句 C 语句到一串控制信号,可以依次分析编码、语义和实现。下面的代码模式与 RTL 是读题示例,具体形式由 ISA、编译结果和题设结构决定。

一、C 语句与常见指令模式

读代码清单之前先认语法:Intel 格式是 目的, 源,dword ptr 一类前缀交代操作数长度,见 操作数长度后缀、内存寻址格式。

C 结构编译出来的指令模式见
赋值、读写局部变量mov,一端是寄存器、另一端是 [ebp − d]数据传送
一维数组 a[i]先算基址 + i×元素大小,再取数;可能合成一条寻址指令,也可能拆为多条变址寻址
二维数组 a[i][j](x86)按行优先时先算 (i×列数+j)×元素大小,再与首地址相加内存寻址格式
x * 2ᵏ、x / 2ᵏ可能使用移位;有符号除法还需处理负数取整差异,溢出也要另查移位
if … else …cmp + 反条件跳转到 else,then 段末尾 jmp 跳过 else选择结构语句
while / do-while循环体末尾一条条件跳转构成回边while 语句、do-while 语句
for初值 mov +(可能先 jmp 到条件判断)+ 体尾自增 + 条件跳转回边for 语句
条件本身可用 cmp / test 后读取标志,也可能由比较分支指令直接判断比较、条件跳转
函数定义与返回典型 x86 栈帧可用 push ebp 建立;是否使用帧指针及返回值位置看调用约定函数定义和调用
函数调用与传参实参 push 入栈 → call(相对寻址),被调用方从 [ebp + 8] 起取参数子程序调用、栈操作

配套的三条口径每年都要用:

  1. 变量住哪:局部变量在 [ebp − d]、参数在 [ebp + 8] 起,栈帧布局见 函数调用时内存结构;也可能全部分配在寄存器里,此时整段代码没有栈帧(2014#44、2024#44)。
  2. 移位位数是 log₂(元素字节数),比例因子才是元素字节数:int 移 2 位、short 移 1 位,2024#44 第 3 问就是把 int 换成 short 改这一位。
  3. 机器码里的多字节字段按端序排,见 大小端;结构体成员和数组元素的地址还受 数据对齐 约束。

指令长度是否等长顺带就是 CISC / RISC 的判据(2017#44),见 不同位数指令。

二、指令格式

  1. 指令 = 操作码 ‖ 寻址方式 ‖ 地址码 —— 操作码位数定指令条数上限,见 指令格式
  2. 寻址方式决定「地址码里的数是操作数、是地址、还是相对偏移」,见 寻址方式
  3. 可先概括成 读谁 → 算什么 → 写回谁,见 寄存器传送语言

三、执行这一行靠固定的几个部件

  1. 取指部件:PC(下一条地址)、IR(当前指令)
  2. 访存接口:MAR(地址,宽度 = 地址线)、MDR(数据,宽度 = 数据线)
  3. 运算部件:ALU 及其暂存器 —— 单总线结构下一个输入必经暂存器、输出必经结果寄存器
  4. 数据仓库:通用寄存器组 GPRs
  5. 指挥者:CU 按 Op(IR) 逐拍发控制信号

结构见 数据通路。

四、指令周期是一条固定的时间轴

取指 → 译码 → 取操作数 → 执行 → 写回 →(有请求则)响应中断

分析总线传送时,先关注两类信号:让谁上总线(Xout)、让谁被写入(Xin),加上 MemR / MemW / ALUop / 多路选择器的选择端,见 指令的控制信号。五个阶段里,取指往往具有公共流程;各阶段具体微操作、PC 增量和耗时仍由指令及数据通路决定:

阶段RTL 模板有效控制信号
取指MAR ← (PC)
MDR ← M(MAR),PC ← (PC)+1
IR ← (MDR)
PCout, MARin
MemR, MDRinE, PC+1
MDRout, IRin
译码指令译码无,由译码器完成
取操作数只由寻址方式决定,见下表
执行A ← (Rx)(单总线才需要单独占一拍)
AC ← (A) op (Ry)
Rxout, Ain
Ryout, ALUop, ACin
写回寄存器Rz ← (AC)ACout, Rzin
写回主存MDR ← (AC)
M(MAR) ← (MDR)
ACout, MDRin
MDRoutE, MemW

2009#44 的题干直接给出了上表前三行,要求照这个格式续写执行阶段——格式跟着题干抄,不要自创。

几种常见寻址方式取操作数的示例:

寻址方式RTL访存次数
立即数操作数就在 IR 里,不必取0
寄存器直接A ← (Ri)0
寄存器间接 (Ri)MAR ← (Ri);MDR ← M(MAR)1
基址 / 变址(带位移)先用 ALU 算有效地址 AC ← (Ri) + 位移,再 MAR ← (AC);MDR ← M(MAR)1
存储器间接上面两拍做两遍:先取出地址,再取出操作数2

三点写法上的约定,比记信号名更要紧:

  1. 暂存器和结果寄存器的名字随题目图变:2009#44 叫 A 和 AC,2015#43 叫 T,教材里常写成 Y 和 Z。照图上的名字写,见 暂存器。
  2. MDR 有两组进出信号:连内总线的是 MDRin / MDRout,连数据总线(DB)那一侧的是 MDRinE / MDRoutE。读主存写 MDRinE、写主存写 MDRoutE,方向弄反是这类题的常见失分点。
  3. 多选器型数据通路不写 Xin / Xout:改成对每个 MUX 回答「这一拍它选哪一路」再写 0/1/2,2026#44 就是逐个信号问这个。

语法与符号见 寄存器传送语言,寻址方式见 寻址方式。

五、把这条时间轴切成五段并重叠,就是流水线

IF → ID → EX → MEM → WB,重叠后只多出三类冒险:结构、数据、控制,见 流水线冒险。

各类题的解法

两种形态各走一路:给了指令格式和数据通路的,按前四条的次序走;给了 C 源码和机器级代码清单的,参看“代码清单:地址、寻址方式与字段解释”。

先把字段翻成一句寄存器传送

不要先动二进制。先把每个字段翻成自然语言,再压成一行:

读谁 → 算什么 → 写回谁

语法见 寄存器传送语言。这一步先把操作数方向和数据去向定下来,位串是最后一步的事。

数一遍位宽

要求的量由什么决定
指令条数上限操作码位数
通用寄存器个数寄存器编号字段的位数
MAR 位数地址线宽度,不是字长
MDR 位数数据线宽度
主存单元宽度编址单位,按字节编址就是 8 位
多路选择器的控制信号位数⌈log₂(输入路数)⌉

2021#43 和 2026#43 就在 MAR / MDR 和「按字节编址推不出寄存器宽度」上设坑。相关指标见 指令格式 与 计算机性能指标。

读结构图

  1. 先给 PC、IR、MAR、MDR、ALU、GPRs、暂存器逐个标出输入来自哪、输出去哪;
  2. 判断是单总线,还是多路选择器加专用通路;
  3. 单总线:一拍只允许一个部件把数据放上总线,所以 ALU 的一个输入必须先进暂存器,输出也要先落到结果寄存器(两者的名字随题目图变)。2015#43 和 2022#43 直接问「为什么要设置暂存器」;
  4. 多选器型:每个 MUX 对应一个控制信号,先回答「这一拍它该选哪一路」,再写 0/1。2024#43 和 2026#44 是这类。

结构见 数据通路。

节拍与控制信号

阶段表和信号写法在知识框架第四条里,落笔时按三条走:

  1. 一拍写一行,先写功能再写信号。功能用 ← 写成一句寄存器传送,信号从这句话里读出来:数据流入某部件就写 Xin,流出就写 Xout,不要凭记忆背信号名。
  2. 不冲突的动作合并到同一拍。单总线上一拍只允许一个部件把数据放上总线,除此之外互不干扰的两个动作可以写进一行、用逗号隔开——2009#44 的另一种答案就靠 MDR ← M(MAR), A ← (R0) 少用一拍。
  3. 周期数不能套经验值。「取指 3 拍」这种数字不能直接用,一次访存本身可能占多个周期:2022#43 给的条件是「从发出主存读命令到数据送到 MDR 共需 5 个时钟周期」,取指阶段因此至少 7 个周期。

代码清单:地址、寻址方式与字段解释

给了 C 源码和机器级代码清单的那五年(2014、2017、2019、2023、2024),可按下面几类分析。地址关系先写在草稿上:

下条指令地址 = 本条指令地址 + 本条机器码字节数
代码段长度   = 末条指令起始地址 + 末条指令字节数 − 首条指令地址
转移目标地址 = 下条指令地址 + 偏移量
偏移量       = 目标地址 − 下条指令地址
  1. 求下条地址或函数长度:数机器码字节数。2017#44 从 push ebp 数到 ret 得 60H = 96B。
  2. 判寻址方式:题设中采用 PC 相对位移的跳转和 call 属于 相对寻址;0(R4) 是寄存器间接(基址寻址);[ebp − 8] 是用基址寻址访问栈帧;[ecx + edx×4 + 位移] 是基址 + 比例变址 + 位移;指令里写死的常数是立即数寻址。
  3. 求目标地址或偏移量:先查题设 ISA 对 PC 基准的定义;下面 x86 示例采用下一条指令地址。2023#44 的 jmp 是 00401079H + 2 + 09H = 00401084H;2019#45 的 call 偏移是 00401000H − 0040102AH = FFFFFFD6H。偏移单位不是字节时还要乘一条指令的长度,2014#44 的公式因此是 (PC) + 4 + OFFSET × 4。
  4. 判端序:把偏移量或位移量字段的字节序和它该表示的数值对照,低字节先出现就是小端——D6 FF FF FF ↔ FFFFFFD6H(2019#45)、00 20 42 00 ↔ 00422000H(2023#44)。反过来,题目给定小端时用它把内存字节拼成机器数(2024#44)。
  5. 反推寄存器与变量的对应:谁被「乘元素大小」就是下标变量,谁被当基址相加就是数组首地址,谁在自己身上累加就是 sum。2024#44 第 1 问就是这一步;2023#44 由「一行 64 个 int」反推出 ecx = i × 256。

问到「这段代码取指会不会缺页」「a[i] 在哪一页」就接到 存储系统 那条地址翻译链上,去掉低 log₂(页大小) 位取页号即可。

时间指标与流水线

问的是公式陷阱
CPU 执行时间指令数 × CPI × 时钟周期时钟周期和主频不要弄反
MIPS主频 ÷ (CPI × 10⁶)
单发射流水线总周期数等节拍、每拍推进时:阶段数 + 指令数 − 1 + 额外停顿拍数多种停顿可能重叠,先画时空表避免重复计数

在题设采用无额外缓冲的顺序流水线时,前一条指令在译码阶段停顿,可能连带阻塞后续取指;是否传播停顿要按流水线结构判断。2012#44 和 2014#44 都要求指出阻塞位置和原因,见 流水线冒险。

汇编追踪:用地址和状态验证解释

遇到 a[i],先写 EA=base+i×sizeof(a[0]),再对应指令中的比例因子、位移和寄存器;二维数组要先将行列下标换成线性下标。这样即使题目修改元素类型或列数,也能重新推导,而不依赖某一段汇编模板。

分支题先标出每条指令的字节长度、顺序后继和跳转目标,再追踪控制流。注意实际机器码可能经过优化,函数不一定建立栈帧,比较也不一定使用 cmp。解释应以题给指令说明与清单为准。

历年题索引

上面这些要点用熟就已经能应付大部分小问,下面这张表用于按考点选题和对照不同问法。

真题主线这一年特别问了什么
2009#44单总线数据通路仿照给出的节拍表列出执行阶段的控制信号
2010#43指令格式 + 机器码转移目标范围、执行后哪些寄存器和存储单元变化
2012#44移位指令 + 五段流水线指出两处阻塞原因并画流水线图
2013#44条件转移 + 标志寄存器无符号数「≤」转移要用哪几个标志位
2014#44分支指令 + 相对寻址求 OFFSET 并推出目标地址公式
2015#43单总线 CPU 结构图暂存器 T 的作用、补全数据通路连线
2015#44机器码 + 控制信号填执行过程中 ①~⑧ 的控制信号
2017#44机器级代码 + CISC/RISC算 cmp 执行后的 CF、能否用移位实现乘 2
2019#45函数调用 + call 相对寻址算 call 的偏移量并判断端序
2020#43无乘法指令的机器三种实现方式下执行时间的长短比较
2021#43R/I/J 型指令格式立即数的扩展方式、无条件转移的格式
2022#43数据通路 + 标志位写 SF 与 OF 的逻辑表达式、取指最少几个周期
2023#44机器级代码 + 寻址方式两条跳转指令的目标地址计算、大小端
2024#43控制信号 + ALU 标志slli 与 lw 的 Ext 和 ALUctr 各取什么值
2025#44补码除法器数据通路除法异常的两种情形与异常响应中 CPU 的动作
2026#43指令格式 + 表达式补全实现 y = 16x − 5 的四条指令编码
2026#44数据通路 + 扩展器EXTOP 至少几位、左移指令周期的控制信号

易错清单

  • 转移目标地址漏掉 PC 自增和偏移缩放。形如 (PC) + 2 + 2 × OFFSET,两项都不能省,见 相对寻址。
  • 偏移量没有先符号扩展。一律先扩展到地址宽度再参与运算。
  • 字节序方向写反。D6 FF FF FF 表示的是 FFFFFFD6H,写成 D6FFFFFFH 会连带错掉「端序」和「机器数」两问(2019#45、2024#44)。
  • 把加法器的进位直接当成 CF。减法和 cmp 的借位标志是进位输出取反,2017#44 由 C = 0 得 CF = 1。
  • 以为移位能通吃「乘 2」。整型可以,浮点不行——float 的机器数含阶码和隐含的最高有效位(2017#44)。
  • 单总线一拍写了两个源上总线。这是数据通路题最常见的整段失分。
  • 溢出被当成自动转异常。要靠运算指令后面的陷阱指令才会转到异常处理程序。
  • 开 / 关中断当成普通指令。它们是特权指令,用户态不可用,2021#45 专门问这一点。

异常响应由硬件完成的动作是固定的四句:关中断、保存断点(PC 与 PSW)、切到内核态、按向量转异常处理程序。见 异常。

上一页:存储系统;下一页:I/O 计算。