
目錄
- 堆疊幀是什么
- 大概輪廓
- 函式創建程序
- 函式銷毀程序
堆疊幀是什么
不知大家接觸過 “堆疊幀” 這個詞沒有,我第一次聽以為是函式戰爭,心里怎么想也想不明白,戰爭(堆疊幀)是什么鬼????
然后我理解后才明白 堆疊(Stack)簡單說, 是由于函式運行而臨時占用的記憶體區域,而幀是函式開辟的會為它在堆疊上建立一個幀(frame)
我們了解后,那堆疊幀有什么用呢?
其實我們在學習C語言的時候會用很多的疑問,比如:
1.main函式肯定是要被呼叫的,那是被誰呼叫的呢?
2.函式里面的區域變數是怎么創建的?
3.區域變數又為什么是默認是隨機值?而全域變數默認卻是0?
4.函式是怎么傳遞引數的?引數的順序又是怎么樣的?
5.函式呼叫詳細程序是怎么樣的?呼叫后是怎么回傳的?
讓我們帶著上面的疑問來一步步刨析吧,
大概輪廓
既然用到了函式,那我們就寫一個簡單的加法函式來看看程序是怎么樣的吧,代碼如下:
#include <stdio.h>
int Add(int x,int y)
{
int z=0;
z=x+y;
return z;
}
int main()
{
int a=2;
int b=3;
int c=0;
c=Add(a,b);
printf("%d ",c);
return 0;
}
先說明一下我平常用的環境是vs2019,但是vs2019封裝細節太多了,不容易看到整個匯編程序,所以這里我用的是 vs2010版本,由于環境不同,下面講解的一些細節方面略有差異,但大體邏輯是不變的,
我們先來回答第一個問題,main函式是被誰呼叫的,


當除錯的游標移動到這里,我們按F11回傳呼叫main函式的函式,發現了呼叫main函式的是 __tmainCRTStartup函式 而這個函式又是被 mainCRTStartup函式呼叫的,
而函式是在堆疊上是靠暫存器 esp(堆疊頂指標)和ebp(堆疊底指標)來維護的,并且在堆疊區是是先使用高地址再使用底地址的,圖片分析如下:

這就是main函式和Add函式在堆疊區上的大概輪廓,下面再讓我們帶著問題刨析main函式的具體創建程序,
函式創建程序
先讓我們看看main函式的匯編是怎么樣的?

除錯到匯編:

接下來就是一步步的分析了,話不多說上圖:

所以就解釋了函式里面區域變數的創建程序,以及為什么區域變數會是隨機值,
當main函式創建好變數后就要開始呼叫Add函式了,我們再分析又是怎么呼叫的
圖片如下:

總之函式的創建是一步步的壓堆疊程序,已經ebp 和esp 指標的變化程序,
所以函式的傳參程序是先從后面開始時傳的,先拷貝b再拷貝a,
形參存放在實參的那個函式當中的,
并且函式的形參只是實參的一份臨時拷貝,改變形參不會影響實參,
函式銷毀程序
函式創建執行相對于的功能后要銷毀的,那是怎么樣銷毀呢?
其實函式的堆疊幀是靠esp 和ebp 指標來維護的,我們只要把ebp 賦值給 esp那么esp 和原來壓進來的ebp 又維護能上一層的函式了,分析圖片如下:

好了,分析到這里整個函式的程序就大概就是這樣了,大家對開始的問題是不是已經有答案了呢?歡迎大家在評論區補充和留言,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/292770.html
標籤:其他
