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都可以计算“有效偏移”,可用于更有效地进行数学运算