⚙️ 第一章 对程序员来说,CPU到底是什么
📄 一句话概括

站在程序员的角度看,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 秒实验

  1. 写一行 a = 3 + 5,在心里数一遍:它至少要动到寄存器几次?
  2. 用在线编译器把这行编译成汇编,找一找 eax 这个名字——那就是累加寄存器。

常见误区

  1. 把寄存器当成【小内存】。它是运算的落脚点,内存是存放的地方,职责不同。
  2. 觉得寄存器叫什么名字是硬件细节、与己无关。寄存器有哪些、怎么用,直接决定了汇编怎么写。
自测三问(点开对答案) 1. 教材说【程序是把寄存器当作对象来描述的】,什么意思? —— 程序里每个动作最终都变成对某个寄存器的操作。 2. 累加寄存器和标志寄存器有什么不同? —— 累加器放参与运算的数据与结果;标志寄存器记上次运算的状态(如结果是否为零)。 3. 数据从内存到运算器,中间要经过哪里? —— 先搬进寄存器,运算结果也先回寄存器,再写回内存。

相关笔记