movl 是汇编里出现次数最多的指令,它只做一件事:把数据搬个地方——但它最常用,因为算、比、跳都得先把数据搬到寄存器里。
10.4 学会了读一行,这一节开始逐条认识指令——从出现最多的那条开始。
一、它只做一件事
movl 就是把数据从一个地方搬到另一个地方,不算、不比、不跳。 搬的两头可以是立即数、寄存器、内存的任意组合(10.4 讲的四种来源)。 这看起来太朴素了,但它是汇编里出现次数最多的指令。 原因也朴素:搬是其他所有动作的前置动作。
二、跑几条看数据流动
movl $5, %eax——5 进 eax,eax 还是 5。
movl %eax, %ebx——eax 的值复制给 ebx,eax 自己不变。
movl $100, _total——把 100 写进那个固定的内存位置。
movl _total, %ecx——再从内存读回来。
最后 addl %ebx, %ecx——ecx 变成 5 + 100 = 105。
整串跑下来,数据怎么流的、谁被改了,全都看得见。
三、三件从数据流里看出来事
movl 只搬不算——5 搬到 eax,还是 5,一点没变。
搬运方向是先源后目的地——movl %eax, %ebx 是把 eax 的值给 ebx。
寄存器可以反复被覆盖——eax 搬出去之后自己不变,但下一次写它就变了。
理解这三条,后面所有指令都只是在它们之上加一点花样。
四、为什么它最常用(回到第一章)
第一章讲过(1.7):CPU 只会【搬、算、比、跳】四件事。 而算、比、跳都要先把数据搬到寄存器里——搬是它们共同的第一步。 所以一段程序里,重复代码的其余三件事,各自前面都站着一条 movl。 这也解释了一个常见现象:优化得很好的代码,往往指令条数没少,少的是搬的次数。
五、动手 Demo:最常用的movl指令
movl 只做一件事:把数据搬个地方。 跑几条看数据是怎么流动的。
prog = [
("movl", "$5", "%eax"),
("movl", "%eax", "%ebx"),
("movl", "$100", "_total"),
("movl", "_total", "%ecx"),
("addl", "%ebx", "%ecx"),
]
vm = VM(prog)
for i, (shown, before, after) in enumerate(vm.run(), 1):
print(i, shown, after["eax"], after["ebx"], after["ecx"])
实跑输出:
--------------------------------------------------------------------
最常用的movl指令
--------------------------------------------------------------------
**movl 是汇编里出现次数最多的指令**——它只做一件事:把数据搬个地方。
跑几条 movl,看数据是怎么流动的:
步 指令 执行后 eax 执行后 ebx 执行后 ecx
----------------------------------------------------------------------
1 movl $5, %eax 5 0 0
2 movl %eax, %ebx 5 5 0
3 movl $100, _total 5 5 0
4 movl _total, %ecx 5 5 100
5 addl %ebx, %ecx 5 5 105
三件事从这几行里就能看出来:
**movl 只搬不算**——5 搬到 eax,还是 5。
**搬运方向是先源后目的地**——movl %eax, %ebx 是把 eax 的值给 ebx。
**_total 那个字节,最后变成了 100**——而 ecx 拿的是 5 + 100。
为什么它最常用?**因为 CPU 只会【搬、算、比、跳】四件事(1.7 讲过),**
而算、比、跳都要先把数据搬到寄存器里——**搬是其他三件事的前置动作。**
实测五步之后:eax=5、ebx=5、ecx=105,_total 那个位置是 100。
movl 只搬不算;搬是算、比、跳的前置动作——所以它出现得最多。
30 秒实验
- 把
movl %eax, %ebx反过来写成movl %ebx, %eax跑一遍,看谁被改了。 - 数一数你随手写的一小段代码,大致要搬多少次数据。
常见误区
- 以为 movl 会顺手做转换或校验。它只搬,不算也不查。
- 以为搬的方向是从左到右。先写源,后写目的地。
自测三问(点开对答案)
1. movl 是做什么的? —— 把数据从一个位置搬到另一个位置,不算、不比、不跳。 2. 为什么它是出现次数最多的指令? —— 因为算、比、跳都要先把数据搬进寄存器,搬是它们共同的前置动作。 3. movl %eax, %ebx 之后 eax 变了吗? —— 没变——movl 是复制,源端的值不会因为搬走而消失。- ☐ 下一节(10.6 将数据存入栈中)
相关笔记
- CPU是寄存器的集合体 — 搬来搬去的目的地是什么
- CPU的处理其实很简单 — 四类动作里的第一类
- 汇编语言的语法是【操作码 操作数】 — 从哪里读到哪里
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引