先驗知識
靜態變數儲存在靜態儲存區,區域性變數儲存在動態儲存區(棧),**存放在**區
暫存器,ebp指向棧底,esp指向棧頂,eip指向正在執行指令的下一條指令,三個暫存器中儲存的都是位址,32位系統,位址為4個位元組即dword
所有寫在函式定義裡面的語句都編譯成指令(驅動cpu)12
3456
78910
1112
1314
15#include
int
fun(
int
a,
int
b);
int
m = 10;
int
main()
int
fun(
int
a,
int
b)
這段**包含兩個函式,因此可以測試函式呼叫,此外還包含了靜態變數、區域性變數、返回值等
測試工具:vc6.0
源**及對應的彙編如下
暫存器及記憶體狀態如下
ebp棧頂初始值為0018ff84h,esp初始為0018ff48h
在每個函式最開始的地方有兩條語句12
push ebp
mov ebp,esp
在函式返回前也有兩條語句12
mov esp,ebp
pop ebp
每執行乙個函式就新開一段棧空間,所謂的開棧空間就是移動ebp棧底,在移動ebp之前,通過push ebp儲存上一級函式的棧底,然後用ebp指向現在函式棧的棧頂,即為當前函式開闢了棧;接著給區域性變數進行位址分配以及儲存現場等,esp不斷向低位址移動,當函式呼叫結束時,esp指回當前函式的棧頂(mov esp,ebp),然後上一級函式的棧頂位址出棧儲存在ebp中(pop ebp)。因此,每乙個函式的棧頂上面都儲存著上一級函式的棧頂位址,用於當前函式結束時能夠返回上一級函式的棧,通過ebp和esp以及壓棧出棧操作對棧進行維護。
main函式對應的彙編**如下12
3456
78910
1112
1314
1516
1718
1920
2122
2324
2526
2728
2930
3132
3334
3536
7:
int
main()
8:
0040105d pop edi
0040105e pop esi
0040105f pop ebx
00401060 add esp,48h
00401063 cmp ebp,esp
00401065 call __chkesp (004010d0)
0040106a mov esp,ebp
0040106c pop ebp
0040106d ret
fun函式的彙編**理解12
3456
78910
1112
1314
1516
1718
1920
2122
2324
2526
2715:
int
fun(
int
a,
int
b)
16:
004010bb pop edi
// 現場恢復
004010bc pop esi
004010bd pop ebx
004010be mov esp,ebp
// 當前函式棧空間**,以後可重新分配,esp=0018fee8h
004010c0 pop ebp
// ebp恢復為0018ff44h
004010c1 ret
// 返回,等待執行函式呼叫的下一條指令
呼叫fun函式時的記憶體情況
區域性變數i和j儲存在48h空間的開始位置(
高位址),即棧底附近,如下圖
在呼叫fun函式之前,將形參從右至左依次壓棧,如下圖
call fun函式時執行跳轉
區域性變數並不是以壓棧的形式入棧的,而是mov進去的,而且是一次性將位址分配夠(如上的48h和44h個位元組)然後乙個個mov進去,形參是以壓棧的形式入棧的
函式返回值是通過暫存器返回的,估計當返回值超出暫存器的表示能力時會通過棧返回(未測試)
函式呼叫時,專門有個地方儲存著函式的入口位址,到那裡進行跳轉執行
實驗**來自國科大楊力祥老師的開源編譯器原始碼分析課程
程式執行時的記憶體
當乙個源 通過gcc編譯成a.out,執行a.out時 程式便開始了執行之旅 即程序 作業系統為程序分配堆疊空間,隨後把程式執行碼放入文字段,把程式經過初始化的全域性變數和靜態變數放入data 把程式為初始化的全域性變數和靜態變數放入bss段 並對bss段資料初始化為0 之後cpu 段指標指向mai...
c 程式執行時的記憶體分配
c 中,記憶體分為5個區 堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。1 棧 是由編譯器在需要時自動分配,不需要時自動清除的變數儲存區。通常存放區域性變數 函式引數等。2 堆 是由new分配的記憶體塊,由程式設計師釋放 編譯器不管 一般乙個new與乙個delete對應,乙個new與乙個del...
C程式執行時的記憶體分布
該篇部落格是自己學習的總結,如果有 理解的不對的地方,希望大家可以指點。一 c記憶體空間分布圖 二 各記憶體區域詳解 1.區 text 該區域主要存放二進位制可執行檔案。2.資料區 data 資料區可詳細分為三塊區域,分別是唯讀資料區 初始化資料區 未初始化資料區。1 唯讀資料區 ordata 顧名...