📄 一句话概括
高级语言把【意图】和【机器】隔开了——一条意图从 3 条降到 1 条,换平台几乎不用改。
📝 本节和前面几节的关系
3.3 解决了可读,这一节解决可移植——这是高级语言最关键的一步。
一、一条意图要几条语句
意图很简单:把 a 和 b 加起来,存进 total。
汇编要三条:movl a, %eax/addl b, %eax/movl %eax, total。
高级语言要一条:total = a + b。
实测:3 条降到 1 条,正好 3 倍。
二、真正的差距在换平台
条数只是表面。真正的差别是换一颗 CPU 的时候: 机器码和汇编——全部重写。 高级语言——一个字不用改(靠编译器重新生成)。 这才是高级语言最关键的一步:它把【意图】和【机器】隔开了。
三、隔开之后多了什么
程序员终于有余力想结构,而不是想寄存器够不够用。 同一份源码可以编译到多个平台,这是后来一切跨平台的基础。 也多了新的角色:编译器——它替人做翻译,也替人做优化。 代价是多了一层:源码和机器码之间不再一一对应,调试要对着优化后的指令看(第 8 章讲这个)。
四、下一步是结构化
高级语言让写程序变容易了,于是程序变大了。 程序一大,最先崩的是人的阅读能力——这就是 3.5 的正题。 注意这个规律:每一层解决一个问题,就把规模推上一个台阶,然后逼出下一层。
五、动手 Demo:高级语言使程序更加接近人类语言
同一条意图,分别用汇编和高级语言写,数语句条数。 再看换平台时各自要改多少。
asm_src = [
"movl a, %eax",
"addl b, %eax",
"movl %eax, total",
]
hl_src = ["total = a + b"]
print("汇编", len(asm_src), "条")
print("高级语言", len(hl_src), "条")
print("倍数", len(asm_src) / len(hl_src))
实跑输出:
--------------------------------------------------------------------
高级语言使程序更加接近人类语言
--------------------------------------------------------------------
【接近人类语言】这句话可以量:**同一条意图,各层要写几条语句。**
意图:把 a 和 b 加起来,存进 total。
实测两种写法的【语句条数】:**汇编 3 条,高级语言 1 条。**
movl a, %eax
addl b, %eax
movl %eax, total
---- 上面三行,等于下面一行 ----
total = a + b
**从 3 条降到 1 条,正好是 3 倍。**
但真正的差距不在条数,在**换个平台要改多少**:
换 CPU 要改吗 换操作系统要改吗
------------------------------------------------
机器码 全部重写 —(本来就绑死)
汇编 全部重写 部分重写
高级语言 不用改 少量改
**这才是高级语言最关键的一步**:它把【意图】和【机器】隔开了。
也正因为隔开了,**程序员终于有余力去想【结构】而不是【寄存器】**——
**结构化的编程,就是从这一步开始的(3.5)。**
实测:汇编 3 条,高级语言 1 条,正好 3 倍。 但真正的差距是换平台:汇编全部重写,高级语言一个字不用改。
30 秒实验
- 找一段你写的三行代码,想想它在汇编里要几行。
- 想一想:编译器替你做的那层翻译,代价是什么。
常见误区
- 以为高级语言的优势只是【短】。真正优势是可移植。
- 以为有了编译器就不用懂底层。优化和调试仍要懂。
自测三问(点开对答案)
1. 同一条加法,汇编和高级语言各要几条? —— 汇编 3 条,高级语言 1 条,正好 3 倍。 2. 高级语言最关键的一步是什么? —— 把意图和机器隔开:同一份源码换平台不用改,靠编译器重新生成。 3. 隔开之后有什么代价? —— 源码和机器码不再一一对应,多了编译器这一层,调试要对着优化后的指令看。- ☐ 下一节(3.5 重视易懂性的结构化编程)
相关笔记
- 编程语言的第一步是汇编语言 — 上一步
- 重视易懂性的结构化编程 — 程序变大之后的问题
- ⚙️ 程序是怎样跑起来的(第3版) · 索引 — 编译器到底做了什么
- 🧩 面向对象是怎样工作的 · 索引