例項分析C程式執行時的記憶體結構

2022-02-16 00:30:07 字數 3364 閱讀 9902

先驗知識

靜態變數儲存在靜態儲存區,區域性變數儲存在動態儲存區(棧),**存放在**區

暫存器,ebp指向棧底,esp指向棧頂,eip指向正在執行指令的下一條指令,三個暫存器中儲存的都是位址,32位系統,位址為4個位元組即dword

所有寫在函式定義裡面的語句都編譯成指令(驅動cpu)12

3456

78910

1112

1314

15#include

intfun(inta,intb);

intm = 10;

intmain()

intfun(inta,intb)

這段**包含兩個函式,因此可以測試函式呼叫,此外還包含了靜態變數、區域性變數、返回值等

測試工具: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:intmain()

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:intfun(inta,intb)

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 顧名...