【18.7.27】函式呼叫過程的深度理解(棧幀)
阿新 • • 發佈:2018-11-20
函式可以大大減少我們程式的程式碼量,使程式碼寫起來更加的簡潔,使程式碼思路更加清晰。是我們程式猿在編寫程式碼時必不可少的。
那麼函式的呼叫過程就非常的重要,今天讓我們來從一個深的角度去了解一下函式的呼叫過程。
函式的呼叫過程也可以叫做棧幀
棧幀的定義是:棧幀也叫過程活動記錄,是編譯器用來實現過程/函式呼叫的一種資料結構。
每一次函式的呼叫,都會在記憶體中為自己申請一塊空間,這個空間就叫函式執行時堆疊,也就是棧幀。
這塊空間就像棧一樣,都需要去維護,棧頂又暫存器ESP去維護,棧底呢就又暫存器EBP去維護。
接下來我們寫一個簡單的程式碼,去更加具體的瞭解我們的函式呼叫過程。
#include<stdio.h>
int main()
{
int i = 20;
int j = 30;
int k = 0;
k = Add(i,j);
printf("%d\n",k);
return 0;
}
int Add(int x,int y)
{//主函式呼叫Add函式去實現加法的功能
int z = 0;
z = x + y;
return z;
}
開啟除錯,進入呼叫堆疊,看看函式的呼叫邏輯。
根據記憶體中棧的特點是由低到高,我們看出,main函式是被mainCRTStartup函式呼叫。開啟反彙編程式碼。在進去main函式到開始我們的程式碼前有這樣一段反彙編程式碼。
我們把這段反彙編程式碼用影象形象的描述一下。
我們把E4轉化成十進位制,就是228,也就是說,把EBP-228的位置的地址給EDI,然後從EDI開始向高地址存放CCCCCCCC,一次4個位元組,存放39次,十進位制的57次,大小正好也是228.就是把這E4的空間大小,放57個CCCCCC進去,每個4位元組。
看一下記憶體,我們看一下這樣的結果,是不是我們所說的樣子
然後我們接著看反彙編程式碼
繼續畫圖
進入CALL指令,我們就進入的Add函式的內部
我們發現和呼叫main函式前,的準備工作幾乎是一致的。那就說明剛才main函式開始前的操作,是開闢函式空間時的準備工作。