第一次呼吸
复习
- 第三十五章至第三十八章:定义了指令,做出了控制器和 CPU
- 第三十九章:了解了指令流水线
- 第四十章至第四十二章:接上了总线、输入输出和中断
TL;DR
- 这一章把最后的所有系统合到一起,让一台完整的计算机跑起来
- 我们放一段程序进内存,看它从取指到输出,全程自动完成
- 至此,从晶体管到整机,这台机器第一次“活“了过来
正文
零件的时代结束了。运算器、存储器、CPU、总线、外设、中断,全都造好了。今天,我们让它们一起呼吸。
全家福
┌──────────────────────────────────────┐
│ CPU │
│ ┌──────────┐ ┌────────────┐ │
│ │ 控制器 │◀────▶│ 运算器 │ │
│ └──────────┘ └────────────┘ │
│ ▲ ┌──────────────────┐ │
│ └───│ 寄存器 / PC / IR │ │
│ └──────────────────┘ │
└────────────────┬─────────────────────┘
│
┌────┴────┐
│ 总线 │
└────┬────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
┌────────┐ ┌─────────┐ ┌──────────┐
│ 内存 │ │ 缓存 │ │ 输入输出 │
│(存储器) │ └─────────┘ │ 设备 │
└────────┘ └──────────┘
这张图里的每一个方块,都对应前面某一章。它们不再是孤立的零件,而是一个系统。
放一段程序进去
我们在内存里放一段很小的程序,它做一件事:把两个数加起来,再把结果输出到一个灯泡上。
地址 指令
100 LOAD R1, [200] ; 把内存 200 处的数取到 R1
104 LOAD R2, [201] ; 把内存 201 处的数取到 R2
108 ADD R3, R1, R2 ; R3 = R1 + R2
112 STORE [202], R3 ; 把 R3 写回内存 202
116 OUT [202] ; 把内存 202 的内容输出到灯泡
...
200 3
201 5
202 0
看它自己跑起来
接下来,没有任何人干预。时钟开始跳动,CPU 开始工作:
第 1 个周期 取指令:PC=100,把 "LOAD R1,[200]" 取进 IR
第 2 个周期 译码:控制器认出这是一条"加载"指令
执行:从内存 200 取出 3,送进 R1
第 3~5 周期 同理,R2 取到 5
第 6 个周期 取指、译码 "ADD R3,R1,R2"
执行:运算器算出 8,写进 R3
第 7 个周期 把 8 写回内存 202
第 8 个周期 取指、译码 "OUT [202]"
执行:通过总线,把 8 送到输出设备
灯泡亮了——它表示数字 8。
整个过程,没有一只手拨开关,没有一个数被人抄写。机器自己取指令、自己译码、自己运算、自己输出。它活了。
它还会被打断
就在这时,键盘(一个输入设备)被按下了。它拉响中断信号。CPU 不慌不忙:先把当前的程序现场保存下来,去处理键盘中断,处理完再恢复现场,从刚才断掉的地方继续。程序仿佛什么都没发生过。
这就是第四十二章的中断系统在起作用。机器不仅能自动跑,还能同时应付外界的突发状况。
回过头看
从第一章“因为懒,想要一台会算数的机器“,到现在,我们亲手走过了:
晶体管 → 逻辑门 → 加法器 → 运算器
→ 锁存器 → 触发器 → 寄存器 → 存储器
→ 指令 → 控制器 → CPU → 总线 → 外设 → 中断
→ 一台会呼吸的计算机
这就是计算机组成原理的全貌。它不是一堆孤立零件的堆砌,而是一层层搭起来、彼此咬合的整体。
再回头看总览里那四句话,现在应该句句都能体会了:
- 懒是人类进步的第一动力——整台机器,就是“想把活儿交给机器“的产物
- 没有什么问题是加一层解决不了的——从门到 ALU,从寄存器到缓存,处处如此
- 人类所有知识都来源于好奇心和解决问题——每个部件,都是被一个具体问题逼出来的
- 所有庞大学科知识体量均由积累而成——四十多章,也是一小步一小步垒起来的
到这里,组成原理这条线就走完了。但计算机科学远不止于此,远处还有更辽阔的世界:
- 操作系统:怎样管理 CPU、内存、文件和设备
- 编译原理:高级语言如何一步步变成机器能懂的 0 和 1
- 计算机网络:多台计算机怎样连成一张网
- 数据结构与算法:怎样把问题解得更快更好
本站的《计算机科学极简入门指南》还会有更多分册,欢迎继续同行。
如果你想亲手把这些电路搭出来,可以试试 Logisim 这类数字电路模拟器,或者直接玩一遍 nand2tetris 项目——你会发现,这一路学的东西,都能亲手拼一遍。
思考题
在上面那段程序里,如果内存里存的不是指令,而是一串普通数据,CPU 会怎么样?冯·诺依曼体系结构“把程序和数据处理成一样“的优点和风险,分别是什么?
小结
知识点
- CPU、内存、总线、外设、中断如何协同
- 一条程序从取指到输出的完整流程
- 中断如何在程序运行中插入处理
- 从晶体管到整机的完整脉络
参考资料
- Wikipedia(zh):冯·诺依曼结构:存储程序思想
- Wikipedia(zh):指令周期:CPU 执行指令的过程
思考题答案(仅供参考)
CPU 并不知道哪块内存是“指令“、哪块是“数据“,它只会照着 PC 指的地址去取、去译码、去执行。如果那里正好是数据,它也会当成指令去执行,结果往往是一团乱麻。
好处是极大的灵活性:程序可以像数据一样被加载、修改、复制,一台通用机器能跑无数种程序。风险也在于此:一旦指针出错、程序跳到数据区,或者恶意代码把数据伪装成指令,机器就会执行本不该执行的东西——缓冲区溢出攻击就是利用这一点。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪