每個函式呼叫都要壓棧,
棧用來存放區域性變數和形參以及狀態指標,
可是很多時候變數是按程式邏輯動態建立的, 編譯器不可能知道函式塊需要多少區域性變數啊?
比如這樣乙個函式:
void test()
else // 棧的大小應按sizeof(a) 還是 sizeof(b)計算?
_test proc;line 2
push
ebp
movebp, esp
subesp, 12;
0000000ch
................
;line 13
movesp, ebp
popebp
ret0
_test endp
編譯器需要知道區域性變數所需的總空間,即所有區域性變數所需空間的和。樓主的例子裡就是8+4=12
voidtest()
pushebp //*儲存caller的frame基址, push操作會使棧頂暫存器esp位址前移4bytes
movebp,esp //*原棧頂變為新frame的基址,因而棧是連續的
addesp,-
0x08
//*棧頂前移8 bytes, 預留變數a,b的空間,這證明frame的大小的確是編譯時確定的.
mov[ebp-
0x04
],0x00000001
//*區域性變數a賦值1
mov[ebp-
0x08
],0x00000002
//*區域性變數b賦值2
popecx //這個不明白了, ecx計數暫存器, 在這pop它幹啥????
popecx // ????而且還pop兩次?????
popebp //*恢復caller的frame基址
ret//*返回
函式呼叫的確是是個壓棧的過程; 函式返回後,壓棧的資料被彈出。
棧的大小,應該由編譯器和os共同決定吧。
編譯器中,有frame 和 record的概念。來控制函式呼叫和返回。以及發生異常時,棧的回退(unwinded)等。
函式呼叫中其相關資訊和其區域性變數的空間都在棧上分配,而且是編譯器自動分配。
至於你說的是sizeof(a) 還是sizeof(b);個人覺得應該大於sizeof(a) + sizeof(b);
因為函式呼叫的過程,是乙個上下文切換的過程,其間,首先要儲存現場、然後將函式的返回位址及區域性變數壓棧、執行函式、返回、恢復現場。 如果寫過匯程式設計序,這個就很容易理解了。
這些都是有編譯器實現的,具體細節我們不必關心。
alloc 可以在棧上分配記憶體。你可以通過在函式內部定義乙個足夠大陣列,來看看,你的編譯器分配的stack size。
現代系統,都是乙個執行緒乙個棧,所以叫做執行緒棧,windows預設乙個執行緒1mb的棧,每新開乙個執行緒,就配套分配1mb的棧,當然也可以指定大小
注意區分兩種存在方式:乙個是在檔案裡,乙個是在虛擬記憶體裡
靜態和全域性變數儲存在.exe/.dll檔案的資料區,執行時則被載入到虛擬記憶體的某個區域,既不在堆,也不在棧
區域性變數實質上是以**的形式,即相關的push/pop指令,儲存在.exe/.dll檔案的**區,執行時,**被載入到虛擬記憶體的某個區。而執行**裡的push/pop時,區域性變數被壓入/彈出棧
乙個c c 函式呼叫棧的實現
函式呼叫棧的實現。可用於實現簡單的指令碼直譯器。宣告 pragma once const int buffersize 1024 const int growfactor 2 this stack is used as call stack.class tstack push an int void...
matlab中如何檢視被呼叫函式的變數
相信用過matlab的小夥伴們都知道,在介面右側的工作區中可以看到主程式中呼叫的變數,那麼如何看主程式中呼叫的函式的變數呢?其實也很簡單啦,我們可以這麼做 1 將主程式中函式末尾的分號去掉,再次執行程式,在命令列窗 們就可以看到函式中自變數的值 然而,被呼叫函式的程式中的一些變數 常量的值我們如何知...
free 函式是如何知曉記憶體塊大小的?
想要理解這個問題,必須先要了解一下malloc函式的實現。首先在程式執行時,系統會為它分配4g的虛擬記憶體,其中就包括堆 heap 堆是可在執行時 為變數 動態進行記憶體分配的一塊區域,堆頂端稱作program break。malloc分配的記憶體允許隨意釋放,它們被維護於一張空閒記憶體列表中,在後...