在x86-32汇编中"lea eax,[ebx + eax]"和"add eax,ebx"有什么区别?

Ske*_*een 4 x86 assembly

GCC给了我一些汇编代码,在这个声明里面:

lea eax, [ebx+eax]
Run Code Online (Sandbox Code Playgroud)

(英特尔语法)只是好奇,它之间有什么区别,和:

add eax, ebx
Run Code Online (Sandbox Code Playgroud)

是?

eax和ebx包含函数的返回值:)

mov eax, DWORD PTR [ebp+8]
mov DWORD PTR [esp], eax 
call CALC1
mov ebx, eax.
mov eax, DWORD PTR [ebp+8]
mov DWORD PTR [esp], eax
call CALC2
lea eax, [ebx+eax]
Run Code Online (Sandbox Code Playgroud)

NPE*_*NPE 11

立即想到的一个不同之处是lea不会影响旗帜,而是add会影响旗帜.

如果没有看到汇编代码的其余部分,这是否具有任何相关性是不可能的.它可能只是GCC代码生成器的一个人工制品(即它实际上可以为更一般的情况生成代码,或者只是使用lea更灵活的代码)add.


Sed*_*glu 6

您可以将结果放入EAX之外的另一个寄存器中,例如lea edx, eax + ebx.add做不到.

lea还可以有一个额外的第三个操作数,lea eax, ebp + esi + 12这使得它更容易替代add指令.

您还可以将某些(字大小的)乘法运算与它组合在一起,例如lea eax, ebp + eax * 8.

更不用说它更好地描述了意图:)


Ste*_*non 5

从数值结果来看,没有区别。

然而,指令的含义远不止存储在目标寄存器中的实际结果:

  1. 正如aix指出的那样,lea不会根据加法的结果设置标志。这有时对于指令调度目的很有用。

  2. 某些微架构(早期的 Atom 核心)也存在时序差异;具体来说,算术单元和地址生成单元之间的转发结果涉及停顿,并且根据上下文使用add或可以消除这些(非常小的)停顿。lea