Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

程序与程序计数器

复习

  • 从寄存器到存储器:用地址、译码器和存储矩阵实现容量更大的存储器
  • 一台会记事的小计算机:把运算器和存储器组装成能连续计算并保存结果的机器
  • 指令系统基础:指令由操作码和操作数组成,可存入存储器

TL;DR

  • 程序是一串按顺序执行的指令
  • 程序计数器 PC 保存下一条指令的地址
  • 顺序执行时 PC 加一,跳转时 PC 改成目标地址

正文

  把上一章的那些命令,依次放进存储器:

地址指令
0读取地址 20 到 A
1读取地址 21 到 B
2A 与 B 相加
3把结果写到地址 22

  这一串排好队的指令,就是程序(program)。

指向下一条指令

  可是指令安静地躺在存储器里,谁来告诉机器“现在执行哪一条”?

  这就需要一根手指。我们增加一个专用寄存器,叫作程序计数器(PC,Program Counter),专门保存“下一条要执行的指令的地址”。开机时把 PC 清成 0,机器就这样循环工作:

  1. 按 PC 给出的地址取出指令
  2. 把 PC 加一,指向下一条
  3. 执行刚才取出的指令
  4. 回到第 1 步

  取完地址 0,PC 变成 1;取完地址 1,又变成 2。只要时钟继续,机器就会沿着程序一路自动走下去。这条“取指、执行、再取下一条”的循环,就是计算机最核心的心跳。

不总是往下走

  顺序执行只能完成一条直路。可我们想要“如果结果为零就结束”,或者“没有算完就再来一轮”,这些都需要让程序能够改变行走的路线。

  办法是允许指令修改 PC。例如一条“若 Z = 1,跳到地址 8”的指令:条件成立,就把 8 写进 PC;不成立,PC 就保持原来已经加一的值。

  循环也不过如此——把 PC 改回一个较小的地址,程序就绕了回来。重复并不是指令天生会做的事,而是跳转把 PC 反复指回开头造成的。

  还记得那些状态标志吗?它们在这里终于发挥作用:ALU 只负责产生 Z,而跳转指令负责根据 Z 选择下一条路。运算和判断,就此接上了。

谁完成这些小动作

  PC 会指出地址,但“读取指令”“PC 加一”“执行”“写回”这些控制信号,仍然要有人发出。下一章,我们造出那个按时钟逐步发号施令的部件。

思考题 1

  一个循环结束后,若机器忘了把 PC 改回循环开头,会发生什么?

思考题 2

  “PC 加一”只是顺序取下一条指令的简化说法。如果一条指令占两个存储单元,PC 还应该只加一吗?

小结

知识点

  • 程序是有顺序的一串指令
  • PC 保存下一条指令地址
  • 顺序执行、条件跳转与循环都通过改变 PC 实现

参考资料

  1. Wikipedia(zh):程序计数器:保存下一条指令地址的寄存器
  2. Wikipedia(zh):控制流:顺序、分支与循环的组织方式

思考题答案(仅供参考)

思考题 1

  PC 会继续指向循环之后的指令,循环只执行一次就离开了。这样本该重复的工作只剩下一遍,结果多半是错的。可见循环的正确性,依赖于每轮结束都把 PC 送回开头。

思考题 2

  不应该。PC 要指向“下一条指令的地址”,所以应该加上“当前指令占用的单元数”,而不是固定加一。前面为了简单,假设每条指令只占一个单元,才写成加一。真实机器里,这个增量由指令长度决定。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪