【发布时间】:2020-12-18 14:21:47
【问题描述】:
以下C代码:
int sum(int x, int y) {
return x + y;
}
编译为:
add:
leal (%rdi,%rsi), %eax
ret
我只看到lea 用于将内存地址从一个地方移动到另一个地方,但这里似乎将一个值和移动到eax。它是如何工作的?
【问题讨论】:
以下C代码:
int sum(int x, int y) {
return x + y;
}
编译为:
add:
leal (%rdi,%rsi), %eax
ret
我只看到lea 用于将内存地址从一个地方移动到另一个地方,但这里似乎将一个值和移动到eax。它是如何工作的?
【问题讨论】:
确实,lea 是“加载有效地址”的缩写,因此最初是为了进行地址计算。
但是:如果rsi+rdi 的计算结果是地址或某个整数,会有什么不同吗?
对于 CPU 来说没有任何区别!
因此,如果您不需要设置标志,则可以使用此指令而不是 add。
操作rax=rsi+rdi可以使用一个 lea指令或使用两个指令的组合来完成:mov和add。
仅使用一条指令通常比使用两条指令更快更短。
您甚至可以使用指令 (leal (%rsi,%rdi),%rax) 执行 8 位、16 位或 32 位加法,因为通过执行操作 rax=rsi+rdi,您可以隐式执行操作 eax=esi+edi、ax=si+di 和 @ 987654332@.
如果我正确理解您的代码,则 C 代码会完成 32 位加法 (eax=esi+edi)。
【讨论】:
lea 不会影响标志寄存器。在许多情况下,交错由lea 执行的简单算术而不影响进位标志或用于流控制的标志之类的能力对性能至关重要。