2010-10-23 239 views

回答

70

莱亚尔,或执法机关的全称是“加载有效地址”,它正是这样做的:它的地址计算。

在你的榜样地址计算很简单,因为它只是增加了一个偏移量EBX并将结果保存在EAX:

EAX = EBX + 0×10

LEA可以做更多的事情。它可以添加寄存器,将寄存器与常量2,4和8相乘,以计算单词,整数和双精度的地址。它也可以添加一个偏移量。

请注意,lea是特殊的,它永远不会修改标志,即使您将其用作上述示例中的简单添加。编译器有时会利用这个特性并通过替换来补充调度器。出于这个原因,在编译代码中看到lea指令执行简单算术并不罕见。

+0

非常漂亮的编译器解释..really – 2013-01-14 09:53:50

+0

此外,如前所述莱亚尔可以用来做算术运算。但它不设置控制代码。所以,不应该用于条件跳转或条件移动。 – 2013-06-19 08:12:16

+0

梦幻般的答案! – Eloff 2014-02-27 12:51:35

4

lea代表“加载有效地址”;这是一种使用IA32指令集复杂的地址模式来进行算术运算的方法。后缀l是一种区分GNU语法中指令操作数大小的方法,与Linux机器上的指令操作数大小相同。

因此,总之,是的,这是一种附加说明。它也可以同时处理2,4或8的乘法运算。

参见this related question(他们使用的是Intel语法讨论相同的指令):

0

要添加到尼尔斯响应,

来回顾一下,在IA32汇编的addresing模式是一般的形式:

IO(RB,R,S),其中:

IO =立即偏移

RB =基址寄存器

RI =索引寄存器

S =比例因子{1,2,4,8}

因此,有效的地址被计算为* IO + [EB] + [EI] 小号

利尔类似于到像movl这样的其他指令,但它有点特别。 不是从源读取到目标,而是将源的有效地址 复制到目标。如Nils指出的那样,它可以用于生成稍后内存引用的指针,并且对于基本算术运算也可以使用 。

例如:

让注册%EDX包含x的值

利尔 1(%EDX,%EDX,8),%eax中

将加载的有效地址1 + X + 8 * X = 1 + 9倍到寄存器%eax中。

在本质上,操作:

莱亚尔目的地 =>目的地 = 地址

的。如果你熟悉C,它是等价的:

字符* b =&一个;

其中炭一个的地址被分配给字符指针b

多个例子:

让寄存器%eax中保持值x和寄存器%ecx中保持值y

利尔( %eax中,%ecx中,4),%EDX将分配值x + 4Y注册%EDX

利尔 0XB(,%ecx中,5),%EDX将分配值0XB + 5Y = 11 + 5Y到%EDX

利尔(%eax中,%eax中,2),%eax中将分配值3倍到寄存器%eax中

希望这有助于

2

GNU为2.18文档

https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html

AT & T:-4(%EBP),英特尔:[EBP - 4]

,然后英特尔语法是自我解释。

更重要的是,该文档也解释一般的情况:

形式

section:[base + index*scale + disp] 

的Intel语法间接内存引用被转换为AT & T语法

section:disp(base, index, scale) 

其中基址和索引是可选的32位基址和索引寄存器,disp是可选的位移和scale,取值1,2,4和8,乘以索引来计算操作数的地址

事情确实在AT & T有点乱,当我们省略地址的某些部分,例如-4(%ebp),但通过文档中的示例,我们可以轻松推导出所有语法情况。

要真正了解是怎么回事,我建议你看一看指令是如何编码。这是一个很好的教程:http://www.c-jump.com/CIS77/CPU/x86/lecture.html当你看到这些时,就会明白为什么地址的某些部分可能被省略,以及每个表单将被编译到什么地方。

相关问题