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

程序计数器(PC)里装的是下一条指令的地址;顺序执行,不过是它按指令长度一次次往前加。

📝 本节和前面几节的关系

1.2 认完寄存器家族,这一节单独拎出其中最特别的一个——决定程序走路的那个。

一、PC 里装的是什么

不是指令本身,是指令所在的地址。 这一点容易想岔:PC 不装【要做什么】,只装【下一条在哪】。 CPU 每次要取指令,先去问 PC:下一条在哪;取完之后,把 PC 改成【这条的结尾之后】。 所以 PC 是 CPU 里唯一一个每执行一条指令就必被改写的寄存器。

二、顺序执行=PC 一直在做加法

指令在内存里是连续排的,每条占几个字节(不同指令长度不一定一样)。 顺序执行时 PC 的走法特别机械:

当前 PC 指令 长度 执行后 PC
0x0000 mov eax, 3 5 字节 0x0005
0x0005 add eax, 5 5 字节 0x000A
0x000A mov [a], eax 5 字节 0x000F

PC 的前进量由指令长度决定——换个 CPU 家族,同一条指令可能 2 字节也可能 6 字节,PC 的脚步就跟着变。

三、一个容易想错的细节

很多人以为 PC 指的是【当前正在执行的指令】。 实际是它指向下一条(CPU 取指令时读的是 PC 的当前值,取完就加)。 这个细节在讲函数调用时特别关键:call 压进栈的,正是这个【下一条】的地址。 记不住也不要紧,记住这句话就行:PC 是【下一步去哪】的备忘录。

四、为什么它重要到要单独讲一节

因为程序的【流程】在硬件上只有两种形态:PC 正常前进、PC 被改写。 你写的顺序、分支、循环、函数调用,最后都要落到这两件事上。 所以【程序怎么走】这个问题,翻成硬件语言就是【PC 怎么变】。 下一节就看它被改写时会发生什么。

五、动手 Demo:程序计数器一步一步往前走

程序计数器(PC)里装的是下一条指令的地址。 顺序执行时它做的事只有一件:加上本条指令的长度。

code = [("mov eax, 3", 5), ("add eax, 5", 5), ("mov [a], eax", 5)]

pc = 0x0000
for ins, size in code:
    print("PC=0x%04X  %-14s 长度 %d 字节  ->  下一条 PC=0x%04X"
          % (pc, ins, size, pc + size))
    pc += size
print("PC=0x%04X  没有指令了" % pc)

实跑输出:

--------------------------------------------------------------------
程序计数器一步一步往前走
--------------------------------------------------------------------

程序计数器(PC)里装的是**下一条指令的地址**。
顺序执行时它做的事只有一件:加上本条指令的长度。

  当前 PC     这条指令               长度       执行后 PC
  --------------------------------------------------------
  0x0000      mov eax, 3             5 字节     0x0005
  0x0005      add eax, 5             5 字节     0x000A
  0x000A      mov [a], eax           5 字节     0x000F
  0x000F      (之后没有指令了)     -          -

  看着像水往低处流,其实每一条都在给 PC 赋值:
    取指令时   PC = 本条指令的地址
    执行完     PC = 本条地址 + 本条长度

  PC 只管一件事:**下一条去哪儿。**
  把 PC 改成别的地址,程序就不按顺序走了——
  这正是下一节【条件分支与循环】的全部秘密。

看着像水往低处流,其实每一条都在给 PC 赋值。 PC 只管一件事:下一条去哪儿。把它的值改成别的地址,程序就不按顺序走了。

30 秒实验

  1. 用在线编译器把一行 int a = 3 + 5; 编译成汇编,看看指令各占几字节。
  2. 在纸上把三条不同长度的指令排起来,逐步写出 PC 的值。

常见误区

  1. 以为 PC 存的是【当前正在执行的指令】。它指向下一条。
  2. 以为 PC 只是个计数器、不参与逻辑。改 PC 就是改流程——它是最有权力的一行。
自测三问(点开对答案) 1. 程序计数器里装的是什么? —— 下一条要执行的指令的地址。 2. 顺序执行时 PC 怎么变? —— 加上当前这条指令的长度,指向下一条。 3. 为什么说 PC 决定了程序流程? —— 因为流程在硬件上只有两种:PC 正常前进(顺序)与 PC 被改写(分支与循环)。

相关笔记