簡體   English   中英

匯編x86 - “離開”指令

[英]Assembly x86 - “leave” Instruction

據說“離開”指令類似於:

movl %ebp, %esp
popl %ebp

我理解movl %ebp, %esp部分,並且它用於釋放存儲的內存(如本問題中所述 )。

但是popl %ebp代碼的目的是什么?

LEAVEENTER的對應物。 ENTER指令通過首先將EBP推入堆棧然后將ESP復制到EBP設置堆棧幀,因此LEAVE必須執行相反的操作,即將EBP復制到ESP ,然后從堆棧中恢復舊的EBP

如果您想了解有關ENTERLEAVE如何工作的更多信息,請參閱英特爾軟件開發人員手冊第1卷中名為“塊結構語言的程序調用”一節。


enter n,0完全等同於(應該替換為)

push  %ebp
mov   %esp, %ebp     # ebp = esp,  mov  ebp,esp in Intel syntax
sub   $n, %esp       # allocate space on the stack.  Omit if n=0

leave完全等同於

mov   %ebp, %esp     # esp = ebp,  mov  esp,ebp in Intel syntax
pop   %ebp

enter非常慢,編譯器不使用它,但leave很好。 http://agner.org/optimize )。 如果編譯器完全使用堆棧框架(至少是gcc),它們會使用leave 但是如果esp已經等於ebp ,那么pop ebp是最有效的。

popl指令恢復基指針, movl指令恢復堆棧指針。 基指針是堆棧的底部,堆棧指針是頂部。 在離開指令之前,堆棧看起來像這樣:

----Bottom of Caller's stack----
...
Caller's
Variables
...
Function Parameters
----Top of Caller's Stack/Bottom of Callee's stack----   (%ebp)
...
Callee's
Variables
...
---Bottom of Callee's stack----    (%esp)

在移動被調用者堆棧的movl %ebp %esp ,堆棧如下所示:

----Bottom of Caller's stack----
...
Caller's
Variables
...
Function Parameters
----Top of Caller's Stack/Bottom of Callee's stack----   (%ebp) and (%esp)

在恢復調用者堆棧的popl %ebp之后,堆棧如下所示:

----Bottom of Caller's stack----    (%ebp)
...
Caller's
Variables
...
Function Parameters
----Top of Caller's Stack----   (%esp)

enter指令保存調用者堆棧的底部並設置基指針,以便被調用者可以分配他們的堆棧。

另請注意,雖然大多數C編譯器都以這種方式分配堆棧(至少在優化時關閉),如果編寫匯編語言函數,如果需要,可以使用相同的堆棧幀,但是必須一定要poppush它的堆棧,否則當你返回時你會跳轉到一個垃圾地址(這是因為call <somewhere>意味着push <ret address> [或push %eip ], jmp <somewhere>ret表示跳轉到堆棧頂部的地址[或pop %eip ]。 %eip是保存當前指令地址的寄存器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM