2010-10-23 236 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當你看到這些時,就會明白爲什麼地址的某些部分可能被省略,以及每個表單將被編譯到什麼地方。

相關問題