CPU 的寄存器
寄存器是 CPU 里唯一能存住东西的部件。上一节的结构图去掉所有寄存器,剩下的 ALU、译码器、CU 全是组合逻辑——只要输入一撤,输出立刻消失。是寄存器把”时刻”变成了”状态”,让机器能跨越时钟周期记住事情。
教材把寄存器分成”用户可见”和”用户不可见”两组。这个分法的名字起得不好,但它背后的判据是本节最有用的东西,而且它有一个非常具体的后果:进程切换的时候,操作系统到底要保存哪些寄存器。
机制
分类表
| 寄存器 | 全称 | 存什么 | 位数 | 可见性 |
|---|---|---|---|---|
| PC | 程序计数器 | 下一条指令的地址 | 主存地址位数 | ✅ |
| 通用寄存器组 | GPRs(含 ACC) | 操作数、中间结果、地址 | 机器字长 | ✅ |
| PSW | 程序状态字寄存器 | ZF、SF、CF、OF、中断允许位、模式位 | 按标志位数 | ✅ |
| SP | 堆栈指针 | 栈顶地址(通常是 GPRs 中的某一个) | 主存地址位数 | ✅ |
| IR | 指令寄存器 | 当前正在执行的指令 | 指令字长 | ❌ |
| MAR | 存储器地址寄存器 | 要访问的主存单元地址 | 主存地址位数 | ❌ |
| MDR | 存储器数据寄存器 | 与主存交换的数据 | 存储字长 | ❌ |
| 暂存器 T / Y / Z | —— | 总线上传来的中间值 | 机器字长 | ❌ |
| 微指令寄存器 μIR、μPC | —— | 当前微指令、下一条微地址 | 见 5.4.3 | ❌ |
位数那一列比可见性那一列考得更多。 四个高频陷阱:
- MAR 的位数 = 主存地址位数,不是机器字长。地址空间
个单元 → MAR 至少 位。 - MDR 的位数 = 存储字长,不是机器字长。主存按字节编址但一次存取 16 位,MDR 就是 16 位。
- IR 的位数 = 指令字长。变长指令集里按最长的算,或按题目给的”定长指令字格式”直接取。
- PC 的位数 = 主存地址位数,与 MAR 同宽——因为 PC 的内容最终要送进 MAR。
PC 的”加 1”到底加多少
PC 具有自动加”1”的能力,这个”1”指的是一条指令的长度,不是数字 1。
按字节编址、指令 32 位 → PC 加 4;按字编址、一条指令占一个字 → PC 加 1。4.1.3 说过,定长指令格式的一个直接好处就是这个增量是常数,控制器不必等译码结果就能算下一条指令地址。
关键时序:PC 的自增发生在取指阶段内,也就是说指令还没执行完,PC 已经指向下一条了。这是 4.2.2 里 PC 相对寻址”基准是已经加过的 PC”的硬件来源,也是中断响应时”保存断点”保存的正是这个已经加过的值的原因(5.5.3)。
「用户可见」这个说法的准确含义
疑问点:PC 也算用户可见?可怎么对它编程——靠跳转指令吗?那 ACC 为什么反倒不可见了?
前半句的方向完全对:PC 的”可见”确实就是通过转移指令兑现的。后半句的前提要更正——ACC 是用户可见的。
「可见」不等于「能用
MOV直接写」,它的准确含义是三条:
- ISA 定义了它——指令集手册里写明了它的存在和语义
- 程序能观察到它的值——哪怕只能间接观察
- 有指令能改变它——哪怕只能间接改变
PC 三条全中:
JMP/Jcc/CALL/RET都在写 PC,CALL压栈的返回地址就是 PC 的值被程序读到了。而 ARM 更直接——R15 就是 PC,可以像普通通用寄存器一样参与运算。ACC(累加器)是通用寄存器,当然可见。 之所以会觉得它”不可见”,是因为在一地址指令
ADD X里,ACC 是隐含操作数——指令里根本没写它。但**“隐含”说的是”不必在指令里写出来”,“不可见”说的是”ISA 里根本没有它”,这是两个完全不同的意思**。隐含寻址见 4.2.2,一地址指令格式见 4.1.2。反过来看什么才叫真的不可见:暂存器 T 没有编号、任何指令都无法命名它、它的值在两条指令之间不携带任何信息。换一个数据通路结构,它可以根本不存在——多总线结构里就常常不需要它。
疑问点:「用户可见 / 不可见」这个边界划得不太合理,应该按具体功能和行为分
这个批评抓对了一半:判据确实应该是行为的。但结论要反过来——“用户可见”本身就是一条行为判据,只是名字起得差。
它的准确名字是**「是否属于 ISA 状态」**,判据是 4.1.1 那条判据的直接套用:
换一个微体系结构实现,这个寄存器还必须存在、还必须有相同的值吗?
- PC / GPRs / PSW:必须。任何一款兼容实现,程序读到的 PC 和标志位都得一样,否则老程序跑不对。→ ISA 状态
- IR / MAR / MDR / 暂存器:不必。可以多设几个、可以合并、可以流水线化成一排,程序察觉不到。→ 微体系结构状态
按功能分类(存地址的 / 存数据的 / 存状态的)也是一个有用的维度,它决定这个寄存器在数据通路上接在哪。但两个维度回答的是不同问题,不能互相取代:
维度 回答什么问题 可见性(ISA 状态?) 能不能出现在指令里?进程切换时要不要保存? 功能(地址 / 数据 / 状态) 在结构图上接在哪?位数按什么取? 让可见性这条线”合理”的,是它右边那个后果。 操作系统做上下文切换时,保存的恰好就是 ISA 状态那一组:通用寄存器、PC、PSW,一个不多一个不少(见 OS 2.1.4 进程控制、OS 1.3.1 处理器运行模式)。
为什么 IR、MAR、暂存器不用保存? 因为切换只发生在指令边界——上一条指令已经执行完、下一条还没开始。那个时刻,这些寄存器里没有任何跨指令有用的信息:IR 里的指令已经做完了,暂存器里的中间值已经用掉了。
所以这条边界不是分类学上的偏好,而是一条工程约束:它精确划出了”必须被保存和恢复的那一组状态”。 换句话说——如果按你说的”具体行为”来分,分出来的结果和这条线是重合的。
三组寄存器的功能视角
既然功能维度也有用,把它一并摆出来:
| 功能组 | 成员 | 共同点 |
|---|---|---|
| 存地址 | PC、MAR、SP | 位数 = 主存地址位数;内容参与地址运算 |
| 存数据 | GPRs、ACC、MDR、暂存器 | 位数 = 字长或存储字长;内容送 ALU |
| 存状态 | PSW、IR | 内容不是”值”而是”情况”:IR 存的是”要做什么”,PSW 存的是”刚才发生了什么” |
PSW 的双重身份值得单独说:它既是运算的结果(ALU 写入 ZF/SF/CF/OF),又是转移指令的输入(Jcc 读它决定转不转),还是控制器的输入(5.1.2 说过 CU 的三类输入之一)。它是全 CPU 唯一一个同时被数据通路和控制通路读写的寄存器——这就是它在结构图上总被单独画出来的原因。
PSW 里除了四个算术标志,还有中断允许位(IF)和模式位。中断允许位在中断响应时被硬件清零(关中断),在 IRET 时恢复——见 5.5.3。模式位区分用户态和内核态,跨到 OS 那边就是 OS 1.3.1 的全部内容。
边界
边界辨析:隐含 / 不可见
- 隐含:指令里不写出来,但 ISA 定义了它。
ADD X隐含 ACC,PUSH隐含 SP。→ 可见- 不可见:ISA 里根本没有它,程序无法命名也无法观察。暂存器 T、MAR。
判据:指令手册里有没有它的名字。
边界辨析:MDR 位数 / 机器字长
MDR 的位数 = 存储字长(主存一次读写的位数),不是机器字长(ALU 一次处理的位数)。二者常相等,但题目一旦给出”按字节编址、存取单位 16 位、机器字长 16 位”这类条件,就要逐项对号。三个字长的完整区分见 4.1.2。
层次辨析:PC / MAR
二者位数相同、内容都是地址,区别在语义:
- PC 存的一定是指令地址,且是下一条的
- MAR 存的是本次要访问的任意主存单元地址——取指时它装 PC 的值,取数时它装操作数地址
一道题问”取指周期中 MAR 的内容”,答PC 的内容(当前指令地址);问”取指周期结束后 PC 的内容”,答下一条指令的地址。
对照速查
| 寄存器 | 位数取自 | 一句话记法 |
|---|---|---|
| PC | 主存地址位数 | 装地址的,且要能覆盖整个主存 |
| MAR | 主存地址位数 | 同上,是 PC 的下游 |
| MDR | 存储字长 | 主存一次吞吐多少,它就多宽 |
| IR | 指令字长 | 装得下一条完整指令 |
| GPRs / ACC | 机器字长 | ALU 一次算多宽,它就多宽 |
| PSW | 标志位个数 | 存”情况”不存”值” |
| 场景 | 要保存的寄存器 | 理由 |
|---|---|---|
| 进程切换 / 中断处理 | GPRs、PC、PSW | 全部 ISA 状态;切换发生在指令边界,其余寄存器无跨指令信息 |
| 中断隐指令(硬件) | PC、PSW | 只保存断点和状态字,GPRs 由软件在服务程序开头保存 |
考点
- 位数计算:给”按字节编址、地址空间
、存储字长 32 位、指令字长 16 位”,问各寄存器位数。逐条对号:MAR 24,MDR 32,IR 16,PC 24。 - 可见性判断:选择题问”下列哪个寄存器用户不可见”,答案在 IR / MAR / MDR / 暂存器里选。PSW 和 PC 都是可见的,这两个是最常见的误答。
- PC 加多少:按字节编址 + 32 位定长指令 → 加 4。别机械地答 1。
- 取指周期各寄存器内容追踪:见 5.2.2,是本章最稳定的选择题题型。
- “为什么设暂存器”:见 5.1.2,答”单总线一拍只传一个值 + 避免 ALU 输入输出成环”。
链接
- 🏠 返回总览:计算机组成原理第 5 章:中央处理器总览
- ⬅️ 上一节:5.1.2 CPU 的基本结构
- ➡️ 下一节:5.2.1 指令周期
- 🔗 判据来源:4.1.1 指令集体系结构
- 🔗 三个字长:4.1.2 指令的基本格式
- 🔗 OS 对照:OS 2.1.4 进程控制——上下文切换保存的正是 ISA 状态那一组
- 🔗 OS 对照:OS 1.3.1 处理器运行模式——PSW 的模式位
- 📖 名词库:第 5 章名词库