LEAL汇编指令有什么作用?
我对它们之间的区别有点困惑
leal -4(%ebp), %eax
和
movl -4(%ebp), %eax
谁可以给我解释一下这个?
LEA (加载有效地址)只是计算操作数的地址 ,它实际上不会取消引用它。 大多数时候,它只是进行计算,比如数组索引的组合乘法和加法。
在这种情况下,它正在做一个简单的数字减法: leal -4(%ebp), %eax
只是为%eax
寄存器分配%ebp - 4
的值。 它等同于单个sub
指令,除了sub
要求目标与其中一个源相同。
相反, movl
指令访问%ebp - 4
处的内存位置,并将该值存储到%eax
。
如果您希望以不同的编程语言来看待这一点,那么:
int var; [ ... ] func (var, &var);
计算以下(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 ...[...]
由于%rdi
/ %rsi
是第1个/第2个参数,你可以看到lea ...
检索变量的地址 &var
,而mov ...
加载/存储相同的值 var
。
即在汇编中,使用lea
而不是mov
类似于在C / C ++中使用address-of &
operator,而不是变量本身的(值)。
lea
有更多的用途,但你明确地询问了两者之间的区别。
例如:带内存操作数的mov
总是执行内存访问(加载或存储),而lea
的内存操作数仅被视为指针算术 – 即计算并解析地址,但指令本身不会发生内存访问。 这两个:
lea 1234(%eax, %ebx, 8), %ecx movl (%ecx), ecx
结果如下:
movl 1234(%eax, %ebx, 8), %ecx
而以下内容:
leal (%eax, %eax, 4), %eax
将%eax
的值乘以5。
在Intel语法中等同于LEA
,加载有效地址(长?)。
例如,LEA和MOV都可以将具有偏移量的寄存器加载到变量。
MOV还可以将内存位置的内容传输到寄存器,LEA则不能。 LEA和MOV都可以计算“有效偏移”,可用于更有效地进行数学运算