⚙️ 第十章 通过汇编语言认识程序的真面目
📄 一句话概括

现在几乎没人用汇编写程序,但看懂它的能力比过去更值钱:性能、怪问题、底层代码、还有别的一堆东西,都得靠这套阅读能力。

📝 本节和前面几节的关系

前面十一节把汇编的各块都摊开看过了,这一节收口:这些东西到底用来干什么。

一、先回答那个常见问题

最常听到的一句是:现在谁还写汇编,学了有什么用? 先承认这句话对了一半:确实几乎没人再拿汇编写业务程序了。 但它问的是【写】,而这本书要做的是【读】。 读写是两件事——就像没人用摩尔斯电码聊天,但懂它仍然有用。

二、五个实实在在的用处

看懂程序的真面目:高级语言那些自动加上的东西,汇编里全摊在明面上。 判断性能:一段代码到底搬了几次内存,看一眼汇编就知道了。 排查怪问题:越界、栈损坏、未定义行为,往往只有汇编能解释。 写底层代码:驱动、引导程序、嵌入式,绕不开。 看懂别的东西:字节码、反汇编、漏洞分析,全是同一套阅读能力。

三、用一行 C 收口

整章下来最好的收口,是回头看那行最短的代码:int add(int a, int b) { return a + b; }。 它落到汇编是六条指令:压栈底、建栈底、取参数、做加法、恢复栈底、返回。 六条里只有一条在【算】——加那一下。 其余五条都在忙同一件事:维护那套【函数进出】的规矩。 这就是这一章想让人看到的东西。

四、这一课到这里的位置

前十章其实在做同一件事:把【程序跑起来】这条链子从底往上一节一节摸清楚。 第一章到第四章讲 CPU 和内存怎么工作;第五、六章讲磁盘与数据压缩。 第七到第九章讲程序站在什么之上、自己是怎么造出来的。 第十章把链条收回到最底——回到 CPU 真正执行的那一行行指令上。 高级语言里那些看不见的活儿,汇编里一条一条都在那儿。

五、动手 Demo:体验汇编语言的意义

学到这里,回答一个常见问题:现在谁还写汇编,学了有什么用。 用一行 C 收口:看它落到汇编是几条指令。

c_line = "int add(int a, int b) { return a + b; }"
asm = ["pushl %ebp", "movl %esp, %ebp", "movl 8(%ebp), %eax",
       "addl 12(%ebp), %eax", "popl %ebp", "ret"]
print(c_line)
print("落到汇编", len(asm), "条指令;其中真正在算的只有", 1, "条")
print("其余", len(asm) - 1, "条都在维护函数进出的规矩")

实跑输出:

--------------------------------------------------------------------
体验汇编语言的意义
--------------------------------------------------------------------

学到这里,回答一个常见问题:**现在谁还写汇编,学了有什么用?**

  用处                 具体是什么
  ------------------------------------------------------------------------
  看懂程序的真面目     高级语言那些【自动加上的东西】,汇编里全摊在明面上
  判断性能             一段代码到底搬了几次内存,看一眼汇编就知道了
  排查怪问题           越界、栈损坏、未定义行为,往往只有汇编能解释
  写底层代码           驱动、引导程序、嵌入式,绕不开
  看懂别的东西         字节码、反汇编、漏洞分析,全是同一套阅读能力

  最后用一个最小的例子收口——**一行 C,落到汇编是几条指令:**

        int add(int a, int b) { return a + b; }
                              ↓
        pushl %ebp              建立栈帧
        movl  %esp, %ebp
        movl  8(%ebp), %eax     取第一个参数
        addl  12(%ebp), %eax    加第二个参数
        popl  %ebp              恢复
        ret                     返回

  **一行代码,六条指令——而其中只有一条在【算】。**
  其余五条都在忙同一件事:**维护那套【函数进出】的规矩。**

  这就是本章想让人看到的东西:
  **高级语言里那些看不见的活儿,汇编里一条一条都在那儿。**

实测:一行 C 落到汇编是 6 条指令,其中只有 1 条在算。 高级语言里那些看不见的活儿,汇编里一条一条都在那儿。

30 秒实验

  1. 挑一段你写过的代码,说出它大致用到哪几条指令、搬了几次内存。
  2. 把这一章里你最没看懂的一节重读一遍,再去它引用的前一章对应节看原话。

常见误区

  1. 以为学汇编是为了【写汇编】。这一章要的是【读】的能力。
  2. 以为高级语言程序员不需要它。性能判断和怪问题排查,全要用到。
自测三问(点开对答案) 1. 为什么现在还要学汇编? —— 因为要的是阅读能力:判断性能、排查怪问题、写底层代码、看懂字节码与反汇编。 2. 一行求和的 C 落到汇编是几条指令? —— 六条,其中只有一条在做加法,其余五条都在维护函数进出的规矩。 3. 这一章在整本书里的位置是什么? —— 把前面讲过的链条收回到最底层——回到 CPU 真正执行的那些指令上。

相关笔记