lea指令!

最近在看linux-0.11內核,看到lea這個指令,google搜索了一下,轉給大家,一起學習@!

 

先看這個這個語法格式吧:

對AT&T來說,尋址方式比較怪異,但又非常簡潔,語法格式如下:

segreg:base_address(offset_address, index, size)
 
;例子
movl %eax, label1(, $2, $4)
movl %ebx, (label2, $2,)
movl %ecx, (%esp)

其效果爲 segreg:base_address + offset_address + index * size
segreg爲分段模式下段寄存器,base_address爲基址,offset_address 爲偏移,index * size決定了第幾個元素,其中size爲元素長度,只能爲1,2,4,8等等,這些元素都是可選的,index默認爲0,size默認爲1。

 

常見1:

http://www.adam8157.info/blog/2011/01/interesting-opcode-lea/原文:

最近惡補彙編時發現lea指令很有意思, 但大部分書都把它一筆帶過, 同時網上的資料又很少, 所以記一下.

lea, load effective address, 加載有效地址. 指令形式是從存儲器讀數據到寄存器, 效果是將存儲器的有效地址寫入到目的操作數, 簡單說, 就是C語言中的”&”.

例如在32位環境下, 有內存位置標籤foo, 則下面兩行效果相同:

movl $foo, %edi
leal foo, %edi

同時, lea還有個很有用但同時又很難理解的用法, 例如這樣:

leal 5(%edx, %edx, 2), %eax

假設%edx的值爲x, 上面這行會將%eax的值設置爲”3x+5″.

奇怪吧, 一個取址的指令怎麼用來做簡單算術操作了? 其實理解起來也不難, 5(%edx, %edx, 2)是存儲器”3x+5″這個地址中的值, 這個值作爲leal的源操作數會被取地址, 地址是什麼? 自然就是”3x+5″!

值得注意的是, 不管是AT&T還是Intel語法, lea都是加載有效地址, 所以運算結果需得在地址空間能表示的大小範圍內.

PS: 可能有人會問爲什麼不把源操作數寫成5(, %edx, 3), 這個嘛, 因爲這種尋址模式的比例因子只能是1, 2, 4或者8.

 

 

常見2:

尋址方式:
0x4(%esp)的操作是把寄存器esp中的值取出,然後加上4,得到的值作爲地址,間接尋址得到需要的數據
例如:
pushl -0x4(%ecx)
該指令的含義是取出寄存器ecx的值,減去4,將得到的值作爲地址,在內存找到該地址對應的值,將其壓入棧中。
這是執行後的結果:
ecx            0xbff01450
esp            0xbff0143c    0xbff0143c
ebp            0xbff01498    0xbff01498

(gdb) x/x $esp
0xbff0143c:    0x0804840a    
(gdb) x/x 0xbff0144c
0xbff0144c:    0x0804840a
其中,內存0xbff0144c即爲%ecx-4後得到的值

指令LEA的作用和80x86彙編有些類似,即地址傳遞,下面舉例說明:
LEA 0x4(%esp), %ecx
該指令的作用是,取出esp寄存器裏的值,加上4,不再繼續尋址,而是將得到值直接傳遞給ecx;如果是其他指令,則還需進行間接尋址,再傳值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章