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
.
您可以将结果放入EAX之外的另一个寄存器中,例如lea edx, eax + ebx
.add
做不到.
lea
还可以有一个额外的第三个操作数,lea eax, ebp + esi + 12
这使得它更容易替代add
指令.
您还可以将某些(字大小的)乘法运算与它组合在一起,例如lea eax, ebp + eax * 8
.
更不用说它更好地描述了意图:)
从数值结果来看,没有区别。
然而,指令的含义远不止存储在目标寄存器中的实际结果:
正如aix指出的那样,lea
不会根据加法的结果设置标志。这有时对于指令调度目的很有用。
某些微架构(早期的 Atom 核心)也存在时序差异;具体来说,算术单元和地址生成单元之间的转发结果涉及停顿,并且根据上下文使用add
或可以消除这些(非常小的)停顿。lea