我对两者之间的区别有点困惑
leal -4(%ebp), %eax
和
movl -4(%ebp), %eax
谁可以给我解释一下这个?
LEA(加载有效地址)只是计算操作数的地址,它实际上并没有取消引用它。大多数时候,它只是为数组索引进行组合乘加之类的计算。
在这种情况下,它进行了简单的数字减法:只需leal -4(%ebp), %eax
将. 它相当于一条指令,除了 a要求目标与源之一相同。%eax
%ebp - 4
sub
sub
movl
相反,该指令访问位于 的内存位置%ebp - 4
并将该值存储到%eax
.
如果您希望以不同的编程语言来看待这个问题,那么:
int var;
[ ... ]
func (var, &var);
评估为以下 (Linux x86_64) 汇编代码:
[ ... ] 4: 8b 7c 24 0c 移动 0xc(%rsp),%edi 8: 48 8d 74 24 0c lea 0xc(%rsp),%rsi d: e8 xx xx xx xx callq ... <func> [ ... ]
由于%rdi
/%rsi
是第一个/第二个参数,您可以看到它lea ...
检索变量的地址 &var
,而mov ...
加载/存储相同的值 var
。
即在汇编中,使用 oflea
而不是mov
类似于&
在 C/C++ 中使用地址运算符,而不是变量本身的(值)。
lea
用途远不止于此,但您明确询问了两者之间的区别。
举例说明:mov
内存操作数总是执行内存访问(加载或存储),而内存操作数lea
仅被视为指针算术- 即计算和解析地址,但指令本身不会发生内存访问。这两个:
lea 1234(%eax, %ebx, 8), %ecx
movl (%ecx), ecx
结果与以下相同:
movl 1234(%eax, %ebx, 8), %ecx
而以下:
leal (%eax, %eax, 4), %eax
将值乘以%eax
五。
等效LEA
于 Intel 语法,加载有效地址(长?)。
例如,LEA 和 MOV 都可以将带有偏移量的寄存器加载到变量中。
MOV 还可以将内存位置的内容传输到寄存器,LEA 不能。LEA 和 MOV 都可以计算“有效偏移量”,可以更有效地进行数学运算