LEAL汇编指令有什么作用?

Ser*_*rov 19 c x86 assembly

我对它们之间的区别有点困惑

leal -4(%ebp), %eax       
Run Code Online (Sandbox Code Playgroud)

movl -4(%ebp), %eax
Run Code Online (Sandbox Code Playgroud)

谁可以给我解释一下这个?

Ada*_*eld 46

LEA(加载有效地址)只是计算操作数的地址,它实际上不会取消引用它.大多数情况下,它只是进行计算,比如数组索引的组合乘法和加法.

在这种情况下,它正在进行简单的数字减法:leal -4(%ebp), %eax只需为%eax寄存器赋值%ebp - 4.它等同于单个sub指令,除了sub要求目标与其中一个源相同.

movl相反,该指令访问存储器位置%ebp - 4并将该值存储到其中%eax.


Fra*_*kH. 7

如果您希望以不同的编程语言来看待这个,那么:

int var;
[ ... ]
func (var, &var);
Run Code Online (Sandbox Code Playgroud)

计算以下(Linux x86_64)汇编代码:

[ ... ]
   4:   8b 7c 24 0c             mov    0xc(%rsp),%edi
   8:   48 8d 74 24 0c          lea    0xc(%rsp),%rsi
   d:   e8 xx xx xx xx          callq  ... <func>
[ ... ]

由于%rdi/ %rsi是1 /2 参数,可以看到lea ...检索地址 &var的变量,而mov ...加载/存储的 var相同.

即在汇编中,使用lea而不是mov类似于&在C/C++中使用address-of 运算符,而不是变量本身的(值).

lea 有更多的用途,但你明确地询问了两者之间的区别.

例如:mov内存操作数始终执行内存访问(加载或存储),而内存操作数lea仅被视为指针算术 - 即计算并解析地址,但指令本身不会发生内存访问.这两个:

lea 1234(%eax, %ebx, 8), %ecx
movl (%ecx), ecx
Run Code Online (Sandbox Code Playgroud)

结果如下:

movl 1234(%eax, %ebx, 8), %ecx
Run Code Online (Sandbox Code Playgroud)

而以下内容:

leal (%eax, %eax, 4), %eax
Run Code Online (Sandbox Code Playgroud)

将值乘以%eax五.