用汇编语言指挥计算机
复习
- 输入输出系统:I/O 接口连接外设,支持查询、中断和 DMA
- 中断系统:外设可主动通知 CPU,CPU 保存现场后处理再恢复
- 第一次呼吸:把 CPU、存储器、总线和外设合起来,让完整计算机自动运行
TL;DR
- 二进制机器指令又长又难记,人们给每种操作起了短名字,叫助记符
- 用助记符写指令,就是 汇编语言 ;一条汇编通常对应一条机器指令
- 汇编几乎和硬件一一对应,因此贴近机器,但也因此繁琐、依赖具体 CPU
正文
还记得上一章那段程序吗?我们把两段 0 和 1 送进存储器,机器就自己算出了结果。它长这样:
| 地址 | 机器码 | 含义 |
|---|---|---|
| 0 | 0001 00010100 | 把地址 20 的数据读入 A |
| 1 | 0010 00010101 | 把地址 21 的数据读入 B |
| 2 | 0011 00000000 | A 与 B 相加,结果放进 R |
| 3 | 0100 00010110 | 把 R 写到地址 22 |
能跑,但你能一眼看出第 3 行在做什么吗?0100 到底是读、是写,还是加?人脑不擅长记这种“光秃秃的 0 和 1”。
既然机器只认 0 和 1,那就在人和机器之间加一层: 给每个操作码起一个短名字 。
助记符
我们给前面用到的操作码起名:
| 操作码 | 助记符 | 含义 |
|---|---|---|
0001 | LOAD | 从存储器读入一个数 |
0010 | LOAD | 同上,换一个寄存器 |
0011 | ADD | 两个数相加 |
0100 | STORE | 把结果写回存储器 |
0101 | JMP | 无条件跳到某个地址 |
0110 | JZ | 若零标志为 1,就跳到某个地址 |
0111 | HALT | 停机 |
这样,0100 00010110 就可以写成:
STORE [22], R
“把 R 存到地址 22”——读起来几乎就是一句人话。这些短名字,叫作 助记符 (mnemonic)。
把程序改写成汇编
现在把上一章的程序整段改写:
LOAD A, [20]
LOAD B, [21]
ADD R, A, B
STORE [22], R
HALT
对照一下原来的机器码:
| 汇编 | 机器码 |
|---|---|
LOAD A, [20] | 0001 00010100 |
LOAD B, [21] | 0010 00010101 |
ADD R, A, B | 0011 00000000 |
STORE [22], R | 0100 00010110 |
HALT | 0111 00000000 |
每一条汇编,都对应一条机器指令。这种“用助记符写指令”的语言,就叫 汇编语言 (assembly language);把汇编翻译成机器码的程序,叫 汇编器 (assembler),下一章之后的某章我们再来造它。
于是又多了一层: 在计算机科学里,没有什么问题是加一层解决不了的。
汇编的两面
汇编语言的好处很明显:
- 可读:
ADD比0011好记多了 - 精确:一条汇编对应一条机器指令,程序耗多少步、用了哪些寄存器,一清二楚
但它也有两个明显的短板:
- 繁琐:寄存器、地址、操作码都要自己写,代码一长就难维护
- 不可移植:不同 CPU 的指令集不一样,为这台机器写的汇编,换一台机器就得重写
可以说,汇编是“离机器最近的语言”。它已经比 0 和 1 友好得多,但骨子里还是在替机器操心。
还差什么
回头看上面那段汇编:20、21、22 这些地址,全是我们手数出来的。如果程序要存一百个数,或者要跳到一个还说不清位置的地方,手工算地址会让人崩溃。
能不能给数据和位置也起个名字,让机器自己去换算地址?这正是下一章要解决的问题。
思考题
既然汇编已经“可读”,为什么我们不干脆一直用汇编写程序?想想:如果要给程序加一个功能,或者要把它搬到另一种 CPU 上,会发生什么?
小结
知识点
- 助记符:用短名字代替二进制操作码
- 汇编语言:用助记符书写机器指令
- 汇编与机器指令基本一一对应
- 汇编可读但繁琐、依赖具体 CPU
- 汇编器:把汇编翻译成机器码
参考资料
- Wikipedia(zh):汇编语言:汇编语言的基本概念
- Wikipedia(zh):助记符:为什么用短名字代替机器码
- 《编码:隐匿在计算机软硬件背后的语言》第 24 章:汇编语言
思考题答案(仅供参考)
因为汇编仍然贴着机器:写的时候要自己安排寄存器、地址和每一步细节,程序一复杂就容易出错、难以阅读。更麻烦的是它不可移植:不同 CPU 的指令集不同,换一台机器往往要整段重写。要“更轻松地让机器做事”,就需要再往上一层,让语言更接近人描述问题的方式,把机器的细节交给翻译程序去操心——这正是后面的高级语言。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪