站在程序员的角度看,CPU 就是一堆寄存器——程序里写的每个动作,最终都是对某个寄存器下达的指令。
1.1 认了四块部件,这一节把其中与程序打交道最多的那一块(寄存器)讲透。
一、程序员眼里的 CPU
硬件工程师看 CPU,看的是引脚和电路;程序员看 CPU,只看一样东西:寄存器。 教材的说法很直接——程序是把寄存器当作对象来描述的。 这句话值得停一下:它不是说【程序存进寄存器】,而是说【你写的每件事,落地时都变成对寄存器的操作】。 所以学汇编、看懂反汇编、判断一处代码快不快,起点都是认出寄存器。
二、主要的八种寄存器
表格见下(这是教材列的八种,也是各类 CPU 大同小异的一套):
| 寄存器 | 管什么 |
|---|---|
| 累加寄存器 | 运算的中心,参与运算的数与结果先放这里 |
| 标志寄存器 | 上一次运算的结果什么样(是否为零、是否进位) |
| 程序计数器 | 下一条要执行的指令在哪 |
| 基址寄存器 | 数据区(如数组)从哪开始 |
| 变址寄存器 | 相对开头偏移多少 |
| 通用寄存器 | 什么都能放,随心用 |
| 指令寄存器 | 当前正在执行的这一条指令 |
| 栈寄存器 | 栈顶在哪 |
不用背。按用途分三类就够记住:管地址的(程序计数器、基址、变址、栈)、管结果的(累加)、管状态的(标志)。
三、为什么非用寄存器不可
寄存器在 CPU 内部,存取比内存快得多——这是它存在的唯一理由。 那为什么不干脆全用内存?因为速度差距太大:运算器算一次只要一拍,等内存可能要好几百拍。 所以真正的数据流是:内存 → 寄存器 → 运算器 → 寄存器 → 内存。 中间那两步(寄存器到运算器、运算器回寄存器)是 CPU 内部的事,快到几乎不用算。 而两头那两步(内存进、内存出)才是真正花时间的地方——这也解释了为什么【减少内存访问】是性能优化的主线。
四、寄存器是【台面】,不是【仓库】
仓库(内存、硬盘)大而慢,台面(寄存器)小而快。 CPU 每次只处理很少的几个数,台面刚好够用——这就是为什么寄存器只有几十个,却够装下一场运算。 记住这个分工,后面讲内存、讲缓存、讲栈时都会用到:谁离运算器近,谁就快,也谁就贵。
五、动手 Demo:五个寄存器跑完一条加法
程序里写的每个动作,落到 CPU 上都是对某个寄存器动手。 拿最小的一段代码做样本:a = 3 + 5。
# a = 3 + 5 翻译成汇编
code = [
("mov eax, 3", 3, None),
("add eax, 5", 8, "ZF=0"),
("mov [a], eax", 8, "ZF=0"),
]
pc = 0
for ins, eax, zf in code:
print("PC=0x%04X %-14s 累加器=%d 标志=%s" % (pc, ins, eax, zf or "-"))
pc += 5
实跑输出:
--------------------------------------------------------------------
五个寄存器跑完一条加法
--------------------------------------------------------------------
程序里写的每个动作,落到 CPU 上都是**对某个寄存器动手**。
拿最小的一段代码做样本:a = 3 + 5。
翻译成汇编是这样(右列是注释):
mov eax, 3 把 3 放进累加器 eax
add eax, 5 让 eax 加 5,标志位跟着更新
mov [a], eax 把 eax 的值写回变量 a
步骤 PC 累加器 标志 这一步在干什么
--------------------------------------------------------------------------------
起 0x0000 - - 一片空白,PC 指着第一条
1 0x0000 3 - mov:把常数 3 送进累加器
2 0x0005 8 ZF=0 add:运算器算出 8,标志位记下结果不为零
3 0x000A 8 ZF=0 mov:把累加器的值写回内存里的 a
止 0x000F 8 ZF=0 三条执行完,PC 停在末尾
这一趟谁被用到了:
PC 每执行完一条就前进——它管【走到哪了】
累加器 eax 全程装数据——它管【正在算什么】
标志寄存器 被 add 更新——它管【上一次结果怎么样】
基址/变址 这段没用上,讲数组时出场
栈寄存器 这段没用上,讲函数调用时出场
**CPU 不记住任何事——除非你把东西放进某个寄存器。**
三个动作动到的寄存器各不同:PC 管走到哪、累加器管算什么、标志位管上次结果如何。 CPU 不主动记住任何事——除非你把东西放进某个寄存器。
30 秒实验
- 写一行
a = 3 + 5,在心里数一遍:它至少要动到寄存器几次? - 用在线编译器把这行编译成汇编,找一找
eax这个名字——那就是累加寄存器。
常见误区
- 把寄存器当成【小内存】。它是运算的落脚点,内存是存放的地方,职责不同。
- 觉得寄存器叫什么名字是硬件细节、与己无关。寄存器有哪些、怎么用,直接决定了汇编怎么写。
自测三问(点开对答案)
1. 教材说【程序是把寄存器当作对象来描述的】,什么意思? —— 程序里每个动作最终都变成对某个寄存器的操作。 2. 累加寄存器和标志寄存器有什么不同? —— 累加器放参与运算的数据与结果;标志寄存器记上次运算的状态(如结果是否为零)。 3. 数据从内存到运算器,中间要经过哪里? —— 先搬进寄存器,运算结果也先回寄存器,再写回内存。- ☐ 下一节(1.3 决定程序流程的程序计数器)
相关笔记
- 看一看CPU的内部构造 — 四块部件怎么分工
- 决定程序流程的程序计数器 — 单独拎出最特别的那个寄存器
- Z80 CPU 的寄存器结构 — 姊妹篇里一套真实的寄存器家底
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引