LEA指令的目的是什么?

对我来说,它看起来像一个时髦的MOV。 它的目的是什么,我应该什么时候使用它?


正如其他人指出的那样,LEA(加载有效地址)通常被用作执行某些计算的“技巧”,但这不是它的主要目的。 x86指令集旨在支持像Pascal和C这样的高级语言,其中数组(特别是int或小结构数组)很常见。 例如,考虑一个表示(x,y)坐标的结构:

struct Point
{
     int xcoord;
     int ycoord;
};

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

int y = points[i].ycoord;

其中points[]是一个Point数组。 假设数组的基数已经在EBX ,并且变量iEAX ,并且xcoordycoord每个都是32位(所以ycoord在结构体中的偏移量是4个字节),可以将此语句编译为:

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

这将土地yEDX 。 比例因子8是因为每个Point大小是8个字节。 现在考虑与“地址”运算符&相同的表达式:

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

在这种情况下,你不需要ycoord的价值,但它的地址。 这就是LEA (加载有效地址)的地方。编译器可以生成,而不是MOV

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

这将在ESI加载地址。


Abrash的“大会之禅”:

LEA ,这是执行内存寻址计算但实际上并不寻址内存的唯一指令。 LEA接受一个标准的存储器寻址操作数,但只不过是将计算的存储器偏移量存储在指定的寄存器中,该寄存器可以是任何通用寄存器。

这给了我们什么? ADD没有提供两件事:

  • 用两个或三个操作数执行加法的能力
  • 将结果存储在任何寄存器中的能力; 不只是其中一个源操作数。
  • LEA不会改变标志。

    例子

  • LEA EAX, [ EAX + EBX + 1234567 ]计算EAX + EBX + 1234567 (这是三个操作数)
  • LEA EAX, [ EBX + ECX ]计算EBX + ECX而不会超出结果。
  • 乘以常数(2,3,5或9),如果您使用它像LEA EAX, [ EBX + N * EBX ] (N可以是1,2,4,8)。
  • 其他用例很方便循环使用: LEA EAX, [ EAX + 1 ]INC EAX之间的区别在于后者改变了EFLAGS但前者不改变; 这保持了CMP状态。


    LEA指令的另一个重要特征是它不会改变条件代码(如CFZF ,同时通过ADDMUL等算术指令来计算地址。 该特性降低了指令间的依赖程度,因此为编译器或硬件调度程序的进一步优化留出了空间。

    链接地址: http://www.djcxy.com/p/1993.html

    上一篇: What's the purpose of the LEA instruction?

    下一篇: Difference between StringBuilder and StringBuffer