函數調用過程

函數調用時候:

 1. 棧針寄存器  esp ebp  

             esp 增大的時候棧空間減小,減小的時候棧空間增大,ebp指向棧基址不變。

 2. 調用函數的時候參數由右至左壓棧,棧空間方向是從高地址(棧底)到低地址(棧頂),然後壓入返回地址,函數地址入棧後,EBP入棧,然後把當前ESP的值給EBP,對應的彙編指令

push ebp
mov ebp esp

 這就相當於進入了此函數的棧空間,


下面是轉載內容:

http://blog.163.com/yichangjun1989@126/blog/static/131972028201442221956603/ 

#include <stdio.h>

int func(int param1 ,int param2,int param3)

{

        int var1 = param1;

        int var2 = param2;

        int var3 = param3;

 

        printf("var1=%d,var2=%d,var3=%d",var1,var2,var3);

        return var1;

}

 

int main(int argc, char* argv[])

{

        int result = func(1,2,3);

 

        return 0; 

}

首先說明,在堆棧中變量分佈是從高地址到低地址分佈,EBP是指向棧底的指針,在過程調用中不變,又稱爲幀指針。ESP指向棧頂,程序執行時移動,ESP減小分配空間,ESP增大釋放空間,ESP又稱爲棧指針。

 

下面來逐步分析函數的調用過程

1.函數main執行,main各個參數從右向左逐步壓入棧中,最後壓入返回地址

2.執行第15行,3個參數以從左向右的順序壓入堆棧,及從param3到param1,棧內分佈如下圖:

 3.然後是返回地址入棧:此時的棧內分佈如下:

4.第3行函數調用時,通過跳轉指令進入函數後,函數地址入棧後,EBP入棧,然後把當前ESP的值給EBP,對應的彙編指令

push ebpmov ebp esp

   此時棧頂和棧底指向同一位置,棧內分佈如下:

 

5.第5行開始執行, int var1 = param1; int var2 = param2; int var3 = param3;按申明順序依次存儲。對應的彙編:

mov 0x8(%ebp),%eaxmov %eax,-0x4(%ebp)

  其中將[EBP+0x8]地址裏的內容賦給EAX,即把param的值賦給EAX,然後把EAX的中的值放到[EBP-4]這個地址裏,即把EAX值賦給var1,完成C代碼 int var1 = param1,其他變量雷同。

6.第9行,輸出結果,第10行執行 對應的彙編代碼:

mov  -0x4(%ebp),%eax

 最後通過eax寄存器保存函數的返回值

 

 

7.調用執行函數完畢,局部變量var3,var2,var1一次出棧,EBP恢復原值,返回地址出棧,找到原執行地址,param1,param2,param3依次出棧,函數調用執行完畢


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章