2013-04-07 132 views
0

我讀Professional Assembly Language通過Richard Blum,當你輸入一個電話你應該ESP寄存器的值複製到EBP,他還提供了下面的模板:爲什麼要在呼叫中保持EBP中的ESP?

function_label: 
    pushl %ebp 
    movl %esp, %ebp 
    < normal function code goes here> 
    movl %ebp, %esp 
    popl %ebp 
    ret 

我不明白爲什麼這個是必要的。當你在功能內部推動某個東西時,你顯然打算將其彈回來,從而將ESP恢復爲原始值。

那麼,爲什麼這個模板?
無論如何,EBP註冊的用途是什麼?

我明顯錯過了一些東西,但它是什麼?

+0

這被稱爲堆棧框架,它可以用於創建從函數完成後被破壞的局部變量。 – 2013-04-07 13:22:07

+0

@Sp。爲什麼我不彈出這些局部變量? /爲什麼彈出不會摧毀它們?對不起,有點慢。 – MasterMastic 2013-04-07 13:23:30

+0

也許你需要看看這個答案,更好地解釋,http://stackoverflow.com/questions/3699283/what-is-stack-frame-in-assembly#answer-3700219 – 2013-04-07 13:27:32

回答

2

當你按下功能裏面的東西,你顯然打算彈出回來

這只是對使用堆棧的部分原因。更常見的用法是你的代碼片段中缺少的一個,它存儲局部變量。您在設置EBP後看到的下一個通用代碼是ESP上的減法,相當於本地變量存儲所需的空間量。這當然也很容易平衡,只需在功能結尾添加相同的數量即可。當代碼也使用C99可變長度數組或非標準但通常可用的_alloca()函數時,它會變得更加困難。能夠從EBP恢復ESP使得這很簡單。

更重要的是,可能是而不是這樣設置堆棧幀是必需的。大多數x86編譯器都支持稱爲「幀指針省略」的優化選項。在GVC的-fomit-frame-pointer,/ MSO上打開Oy。這使得EBP寄存器可用於一般用途,這對於x86缺乏cpu寄存器非常有用。

雖然這種優化有一個非常嚴重的缺點。如果沒有EBP寄存器指向堆棧幀的開始,則執行堆棧遍歷將非常困難。當你需要調試你的代碼。堆棧跟蹤對於瞭解代碼如何最終崩潰非常重要。當您從客戶那裏得到崩潰的「核心轉儲」時,這是非常寶貴的。微軟同意在Windows二進制文件上同意turn off the optimization,以便爲其客戶提供診斷崩潰的機會。

相關問題