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

汇编的语法简单到一句话:先写操作码,再写操作数。操作数只有四种来源,认准前缀就不会看错。

📝 本节和前面几节的关系

10.3 分清了四类行,这一节专门讲其中真正干活的那些行怎么写。

一、一句话概括的语法

高级语言的语法要讲一本书,汇编的语法一句话就够:操作码加操作数。 操作码说的是做什么(movl、addl、cmpl),操作数说的是对谁做。 操作数可以有一个或两个,中间用逗号隔开。 就这么简单——所以读汇编的难点从来不是语法,而是【知道每条指令在干什么】。

二、操作数只有四种来源

$5——立即数,就是数字本身。 %eax——寄存器,CPU 手边的小格子。 _total——内存里的一个位置(固定地址的全局变量)。 8(%ebp)——内存,以 ebp 为基准偏 8 字节的地方。 看第一个字符就能判断是哪一种——这是读汇编最实用的一条经验。

三、最容易翻车的一处:顺序

addl %ebx, %eax——先写源,后写目的地。 也就是【把 ebx 加到 eax 上】,不是反过来。 这跟多数人【从左到右】的习惯正好相反,是初学者最容易看错的地方。 有个小办法记:把它读成【把第二个加到第一个上】,多念几遍就顺了。

四、一行的完整结构

把一行切开看,结构其实很规整: 操作码(movl)+ 操作数 1($10)+ 操作数 2(%eax)。 有些指令只有一个操作数(比如 incl %ecx),有些一个都不用(比如 ret)。 标号、注释都可以跟在后面——汇编器会按位置把它们分出来。

五、动手 Demo:汇编语言的语法是【操作码 操作数】

汇编的语法简单到一句话:先写操作码,再写操作数。 把几行汇编逐条切开,看操作码和操作数各是什么。

prog = [
    ("movl $10, %eax", "movl", "$10", "%eax"),
    ("movl $20, %ebx", "movl", "$20", "%ebx"),
    ("addl %ebx, %eax", "addl", "%ebx", "%eax"),
    ("cmpl $30, %eax", "cmpl", "$30", "%eax"),
]
for line, op, a1, a2 in prog:
    print(line, "|", op, "|", a1, "|", a2)

实跑输出:

--------------------------------------------------------------------
汇编语言的语法是【操作码 操作数】
--------------------------------------------------------------------

汇编的语法简单到一句话:**先写操作码,再写操作数。**

  操作码     操作数            合起来的意思
  ---------------------------------------------------
  movl       $5, %eax          把立即数 5 放进 eax
  movl       %eax, %ebx        把 eax 的值复制到 ebx
  addl       $3, %eax          eax 加上 3
  cmpl       $10, %eax         拿 eax 和 10 比较
  leal       8(%ebp), %eax     算出地址放进 eax

  操作数只有四种来源,**认准前缀就不会看错:**

    $5          立即数——就是数字本身
    %eax        寄存器——CPU 手边的小格子
    _total      内存里的一个位置(本 Demo 的写法)
    8(%ebp)     内存——以 ebp 为基准偏 8 字节的地方

  把一段汇编逐行切开,操作码与操作数就一目了然:

  整行                操作码     操作数 1     操作数 2
  -----------------------------------------------------
  movl $10, %eax      movl       $10          %eax
  movl $20, %ebx      movl       $20          %ebx
  addl %ebx, %eax     addl       %ebx         %eax
  cmpl $30, %eax      cmpl       $30          %eax

  **注意 addl %ebx, %eax 的顺序:先写源、后写目的地。**
  这跟多数人【从左到右】的习惯相反,**是初学者最容易看错的地方。**

实测把四行切开后,操作码与操作数一目了然。 注意 addl %ebx, %eax 的顺序:先源、后目的地——这是最容易看错的地方。

30 秒实验

  1. 把 addl %ebx, %eax 读出声来,念成【把 ebx 加到 eax】,多念几遍。
  2. 翻一段真实汇编,把其中每条指令的操作码圈出来。

常见误区

  1. 按从左到右的顺序理解 addl %ebx, %eax。它是先源后目的地。
  2. 以为操作数一定要两个。有的只有一个,有的一个都没有。
自测三问(点开对答案) 1. 汇编的语法结构是什么? —— 操作码加操作数:操作码表示做什么,操作数表示对谁做。 2. 操作数有哪四种来源? —— 立即数($开头)、寄存器(%开头)、固定内存位置、以寄存器为基准的偏移内存。 3. addl %ebx, %eax 是什么意思? —— 把 ebx 的值加到 eax 上——先写源,后写目的地。

相关笔记