对我来说,这就像一部时髦的电影。它的用途是什么?我应该什么时候使用它?


当前回答

lea是“加载有效地址”的缩写。它将源操作数的位置引用地址加载到目标操作数。例如,您可以使用它:

lea ebx, [ebx+eax*8]

用一条指令进一步移动ebx指针eax项(在64位/元素数组中)。基本上,您可以从x86体系结构支持的复杂寻址模式中受益,从而有效地操作指针。

其他回答

正如其他人所指出的,LEA(负载有效地址)经常被用作进行某些计算的“技巧”,但这并不是它的主要目的。x86指令集是为支持Pascal和C等高级语言而设计的,在这些语言中,数组特别是int数组或小型结构是常见的。例如,考虑表示(x,y)坐标的结构:

struct Point
{
     int xcoord;
     int ycoord;
};

现在想象一下这样的陈述:

int y = points[i].ycoord;

其中points[]是Point的数组。假设数组的基已经在EBX中,变量i在EAX中,xcoord和ycoord各为32位(因此ycoord在结构中的偏移量为4字节),则该语句可以编译为:

MOV EDX, [EBX + 8*EAX + 4]    ; right side is "effective address"

其将在EDX中降落y。比例因子为8是因为每个点的大小为8字节。现在考虑与“address of”运算符使用的相同表达式&:

int *p = &points[i].ycoord;

在这种情况下,您不需要ycoord的值,而是需要它的地址。这就是LEA(加载有效地址)的作用

LEA ESI, [EBX + 8*EAX + 4]

这将在ESI中加载地址。

LEA指令的另一个重要特征是它不会改变条件代码(如CF和ZF),而通过ADD或MUL等算术指令计算地址则会改变。这一特性降低了指令之间的依赖程度,从而为编译器或硬件调度器的进一步优化腾出了空间。

LEA指令可用于避免CPU对有效地址进行耗时的计算。如果地址被重复使用,则将其存储在寄存器中而不是每次使用时计算有效地址更有效。

lea是“加载有效地址”的缩写。它将源操作数的位置引用地址加载到目标操作数。例如,您可以使用它:

lea ebx, [ebx+eax*8]

用一条指令进一步移动ebx指针eax项(在64位/元素数组中)。基本上,您可以从x86体系结构支持的复杂寻址模式中受益,从而有效地操作指针。

在MOV上使用LEA的最大原因是,如果需要对用于计算地址的寄存器执行算术运算。实际上,您可以在几个寄存器上组合有效地“免费”执行相当于指针运算的操作

真正令人困惑的是,您通常会像MOV一样编写LEA,但实际上并没有取消对内存的引用。换句话说:

移动EAX,[ESP+4]

这将把ESP+4点的内容移动到EAX中。

LEA-EAX,[EBX*8]

这将把有效地址EBX*8移动到EAX,而不是在该位置找到的地址。正如您所看到的,当MOV仅限于加法/减法时,也可以乘以2的因子(缩放)。