2015-10-04 111 views
2

看下面的代碼:
(EBP-0x8中 - > INT)
(EBP-爲0x4 - > INT *)的x86英特爾彙編LEA

=> 0x80483f3 <main+6>: mov DWORD PTR [ebp-0x8],0x0 
    0x80483fa <main+13>: mov DWORD PTR [ebp-0x4],0x0 
    0x8048401 <main+20>: mov DWORD PTR [ebp-0x8],0xa 

    0x8048408 <main+27>: lea eax,[ebp-0x8] 
    0x804840b <main+30>: mov DWORD PTR [ebp-0x4],eax 

    0x804840e <main+33>: mov eax,0x0 
    0x8048413 <main+38>: leave 
    0x8048414 <main+39>: ret 

是對執法機關的命令,在真正需要的? 我知道下面的表達式是錯誤的,無效的,不管左邊的地址是錯誤的,但是沒有類似的方式來表示它嗎?

=> 0x80483f3 <main+6>: mov DWORD PTR [ebp-0x8],0x0 
    0x80483fa <main+13>: mov DWORD PTR [ebp-0x4],0x0 
    0x8048401 <main+20>: mov DWORD PTR [ebp-0x8],0xa 

    0x804840b <main+30>: mov DWORD PTR [ebp-0x4],ebp-0x8 

    0x804840e <main+33>: mov eax,0x0 
    0x8048413 <main+38>: leave 
    0x8048414 <main+39>: ret 

我認爲它不可能,但我想確定。

而最後一個問題,表達ebp-0x8理論上返回的「的ebp寄存器減去0x8的內容」。 因此,表達式[ebp-0x8]將返回地址「內容ebp寄存器減去0x8內存的內容。 現在我想知道如果LEA命令只能獲取內存中某些字節的內容,LEA命令如何獲取內存地址。

對不起,如果有一些愚蠢的問題,但[]有時可能會很混亂。

+0

爲什麼被標記爲[C]?這個問題不是關於C的。我爲你刪除了標籤。 – fuz

+0

對不起,它的代碼是由C源代碼生成的,最初我也想添加它。 – Michael

回答

3

爲了使你的第二個代碼片段工作,你需要做一個單獨的指令減法。換句話說,而不是

DWORD PTR [ebp-0x4],ebp-0x8 

你需要

mov eax,ebp 
sub eax,0x8 
mov DWORD PTR [ebp-0x4],ax 

使用lea的優點是,它結合了算術運算與MOV指令。因此,而不是兩個指令

mov eax,ebp 
sub eax,0x8 

可以使用單指令

lea eax,[ebp-0x8] 

lea指令是指「加載有效地址」。第二個操作數指定地址,並且計算該地址所需的任何計算均由處理器中的地址生成邏輯完成。

另一方面,sub指令使用處理器的通用算術邏輯單元(ALU)。

總之,lea指令通過使用處理器的地址生成邏輯來執行一個否則需要在ALU中完成的數學計算,將兩條指令組合成一條指令。

1

不,這是無效的表達,你不能做的數學表達式與內存地址MOV源操作數,如果指定括號[],這是別的意思是從內存地址提領值除(這完全像非關聯化的C指針,以得到其數值)

的方式,使數學表達式與地址是使用LEA指令,它在你的例子是:

lea eax,[ebp-0x8] 
mov DWORD PTR [ebp-0x4],eax 

注意leamov指令非常不同。

這是來自英特爾手冊第一個定義爲LEA指令:

計算第二個操作數(源 操作數),並將其存儲在第一操作數(目標操作數)的有效地址。

MOV已知是數據傳輸指令,而LEA大多采用計算使用地址數學運算

這是不同MOVLEA之間的幾個例子

mov eax, [ebp-0x8] ; compute new address ebp-0x8 and get its value from new address 
mov eax, ebp-0x8  ; this is invalid 
lea eax, [ebp-0x8] ; compute new address ebp-0x8 and give it to eax