說到EBP就不能忽略了ESP。ESP是一個指針,始終執行堆棧的棧頂。而EBP就是那個所謂的堆棧了。
先看幾個例子吧。
push ebp ; 把ebp,堆棧的0地址壓入堆棧 mov ebp,esp ; 把棧頂指針存入當前堆棧esp,也就是堆棧的esp位置。 push ecx ; 存入 ecx 參數 push 00000002 ; 存入 2 參數 push 00000001 ; 存入 1 參數局 lea ecx,[ebp-04] ; 把堆棧借(用負數)一個位置,4字節長。賦值給ecx,這個值是多半是上層傳遞下來的。 call 00401020 ; 調用指定地址的函數。 mov esp,ebp pop ebp ret .... 00401020處代碼(理解成一個函數): push ebp ; 進入函數代碼了,然后把存入進來的0地址ebp,保存到堆棧。 mov ebp,esp ; esp保存到ebp里面,保存到 push ecx ; 存入 ecx到堆棧中。 mov [ebp-04],ecx ; 堆棧中借一個位置來存放ecx. mov eax,[ebp+08] ; 從堆棧中取值, 上面一個函數,存入的參數參數2 add eax,[ebp+0C] ; 從堆棧中取值,上面一個函數存入的參數1 mov esp,ebp ; 把 ebp首地址的值寫回到 esp中。 pop ebp ; 釋放 ebp中的0地址到ebp中。 ret 0008 ; 釋放掉 可能是釋放掉一個call地址和其中在本次函數中push的一個值。這樣解釋比較合理。(就是使用ebp開辟的一個空間值)
上面代碼主要就是一個,傳入參數調用函數進行一個1+2的計算。
先解釋一下上面代碼:
可以通過這個認識到幾點。
1、如果使用了push ebp mov ebp,esp 操作進行初始化。
那么從堆棧中取值都是ebp+XXX值。。
而往堆棧里面,放入值都是[EBP-XXX],寄存器。這樣的操作。
2、ebp應該就是針對當前函數,作用域獨立存在的一個堆棧的首地址了。
而ESP就是,執行當前棧頂的一個指針,這個作用域是跨越了所有函數調用的。
。。。。個人理解,沒有配圖,請大家參考其他文章相應理解,我僅僅作為個人理解記錄。
想再想想,大學時候,鄙視別人看的書,現在自己也拾起來看了。唉