當我們在學習c語言的時候,寫**一定會用到函式(main函式),但函式在使用過程中是如何呼叫的,當我們從彙編的角度來剖析函式的呼叫,會讓我們對函式的認識剛深一層。
注:使用的工具是vs2017
下面我將通過一段**來剖析函式是如何呼叫的
#include
int add(int
x, int
y)
int main()
函式在呼叫的過程中,是需要為函式來開闢棧空間,用於本次函式的呼叫過程中臨時變數的儲存、現場保護,這塊空間就被稱為函式棧幀。
首先我們來研究一下main函式的彙編**:
int main()
01061731
pop edi
01061732
pop esi
01061733
pop ebx
01061734
mov esp,ebp
01061736
pop ebp
01061737
ret
前面建立棧幀的過程和main函式一樣,其中第一步是先將main函式的ebp 壓棧,目的是為了在返回時能夠返回到main函式的棧底。
將兩數之和放入z中,並最後將z的值放在暫存器eax中
01061731
pop edi
01061732
pop esi
01061733
pop ebx
01061734
mov esp,ebp
01061736
pop ebp
01061737
ret
接下來將會執行pop 操作,也就是出棧,按照順序依次將edi 、esi 、ebx 出棧。然後將ebp 賦值給esp ,ebp 出棧。注:ret 指令會使得出棧一次,並將出棧的內容當做位址,將程式跳轉到該位址處。將add棧幀銷毀。
接下來就會從call指令處繼續向下執行
01061849
add esp,8
0106184c mov dword ptr [ret],eax
將esp 向下移,將形參銷毀,把eax放入ret(ebp-20h) 中。
下面就是對main棧幀的銷毀,和add棧幀的銷毀一樣。
函式呼叫過程(棧幀)
眾所周知,程式每呼叫乙個函式,系統都會為其開闢一塊空間,當它返回時,才收回這塊空間。程式崩潰有一部分原因就是因為無限制的呼叫函式,卻沒有及時返回,導致記憶體空間不夠。為了更好的維護這一塊空間 通常稱為棧空間 我們需要了解兩個暫存器,乙個為 esp 指向棧頂的指標 乙個為 ebp 指向棧底的指標 棧空...
函式棧幀(呼叫過程)
函式棧幀就是在呼叫函式是為其在棧空間上開闢了一段空間,指向過程呼叫,乙個過程呼叫包括將資料 以過程引數和返回值的形式 和控制從 的一部分傳遞到另一部分。我們以以下 為例講解整個函式呼叫過程 int my add int x,int y int main 一 呼叫main 函式 我們從main 函式的...
函式的呼叫過程 棧幀
在談棧幀之前,我們必須要先知道c c 程式記憶體的分配情況。乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放為執行函式而分配的局 部變數 函式引數 返回資料 返回位址等。其操作方式類似於資料結構中的 棧。2 堆區 heap 一般由程式設計師分配釋...