1. 程式人生 > >C++程式碼反彙編後的函式呼叫過程,堆疊暫存器EBP和ESP

C++程式碼反彙編後的函式呼叫過程,堆疊暫存器EBP和ESP

棧是從高地址向低地址生長的。  ebp始終指向當前棧幀的棧底部 , 通過ebp+4中儲存著函式的返回地址 。函式返回時將EBP的值推給EIP ,返回到上一個函幀繼續執行。

ret 與call指令 相反 ,call 將EIP壓入堆疊,然後跳到標號處。

ret 8  在函式返回後將ESP+8 ,平衡棧幀(由被呼叫者平衡棧幀--C呼叫約定)  。 (stdcall由呼叫者平衡棧幀,引數壓入順序也從右向左)

ebp+8儲存著引數1 , ebp+0c 引數2 ,類似....。 前提是使用C(或者stdcall)呼叫約定,引數從右向左開始壓入棧。

每一個函式呼叫的反彙編開始執行前都有

push ebp

mov ebp,esp

sub esp ,0ch  ;棧子空間, 這句的前提是函式有區域性引數 ,開闢的大小也根據編譯器不同而各異,當然肯定大於區域性變數的引數

函式結束後都有以下兩句

mov esp , ebp ;不管前面esp開闢了多少棧空間,通過一個ebp賦值,就全回收了。

pop ebp ; 還原前棧幀的EBP,  //此時ESP = ESP-4  , ESP指向了返回地址

ret ; 即將ESP(其實都是從EBP恢復出來的)儲存的返回地址彈給EIP,返回到呼叫前的地址, , C呼叫還需要平衡棧幀ret 8;(假如兩個引數)

棧是從高地址向低地址生長的。每開闢一個棧幀肯定是在前棧幀的低地址位置。

盜個圖