c 程式的記憶體布局

2021-07-04 19:21:19 字數 1974 閱讀 6682

對任何乙個普通c++程式來講,它都會涉及到

5種不同的資料段。常用的幾個資料段種包含有「程式**段」、「程式資料段」、「程式堆疊段」等。不錯,這幾種資料段都在其中,但除了以上幾種資料段之外,程序還另外包含兩種資料段。下面我們來簡單歸納一下程序對應的記憶體空間中所包含的

5種不同的資料區。

**段

:**段是用來存放可執行檔案的操作指令,也就是說是它是可執行程式在記憶體種的映象。**段需要防止在執行時被非法修改,所以只准許讀取操作,而不允許寫入(修改)操作

——它是不可寫的。

資料段

:資料段用來存放可執行檔案中已初始化全域性變數,換句話說就是存放程式靜態分配的變數和全域性變數。

bss

:bss

段包含了程式中未初始化全域性變數,在記憶體中

bss段全部置零。

堆(

heap

:堆是用於存放程序執行中被動態分配的記憶體段,它大小並不固定,可動態擴張或縮減。當程序呼叫

malloc

/new

等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張);當利用

free

等函式釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)

:棧是使用者存放程式臨時建立的區域性變數,也就是說我們函式括弧「

{}」中定義的變數(但不包括

static

宣告的變數,

static

意味這在資料段中存放變數)。除此以外在函式被呼叫時,其引數也會被壓入發起呼叫的程序棧中,並且待到呼叫結束後,函式的返回值也回被存放回棧中。由於棧的先進先出特點,所以棧特別方便用來儲存

/恢復呼叫現場。從這個意義上將我們可以把堆疊看成乙個臨時資料寄存、交換的記憶體區。

我們要知道,棧中存放的是乙個個被調函式所對應的堆疊幀,當函式

fun1

被呼叫,則

fun1

的堆疊幀入棧,

fun1

返回時,

fun1

的堆疊幀出棧。什麼是堆疊幀呢,堆疊幀其實就是儲存被調函式返回時下一條執行指令的指標、主調函式的堆疊幀的指標、主調函式傳遞給被調函式的實參

(如果有的話

)、被調函式的區域性變數等資訊的乙個結構。

首先,我們要說明的是如何區分每個堆疊幀,或者說,如何知道我現在在使用哪個堆疊幀。和棧密切相關的有

2個暫存器,乙個是

ebp,

乙個是esp

,前者可以叫作棧基址指標,後者可以叫棧頂指標。對於乙個堆疊幀來說,

ebp也叫堆疊幀指標

,它永遠指向這個堆疊幀的某個固定位置

(見上圖

),所以可以根據

ebp來表示乙個堆疊幀,可以通過對

ebp的偏移加減,來在堆疊幀中來來回回的訪問。

esp則是隨著

push

和pop

而不斷移動。因此根據

esp來對堆疊幀進行操作。

再來講一下上圖,乙個堆疊幀的最頂部,是實參,然後是

return address,

這個值是由主調函式中的

call

命令在call

呼叫時自動壓入的,不需要我們關心,

previousframe pointer,

就是主調函式的堆疊幀指標,也就是主調函式的

ebp值。

ebp偏移為正的都是被調函式的區域性變數。

C程式的記憶體布局

c程式的記憶體布局 c程式的典型記憶體表示由以下部分組成 1.文字段 cpu 執行的機器指令 2.初始化資料段 資料段 3.未初始化的資料段 也稱bss段 4.棧 自動變數以及每次函式呼叫時所需儲存的的資訊都放在棧中 5.堆 通常在堆中進行動態儲存分配 如下圖所示 測試 include includ...

C程式的記憶體布局

乙個c程式一直以來都是由以下5個段 pieces 組成 正文段。這是由cpu執行的機器指令部分。通常,正文段是可共享的,所以即使執行的程式 如文字編輯程式 c編譯程式 shell等 在儲存器中也只需有乙個副本 否則會造成資源浪費,試想如果開同樣的程式100個,每個正文段都要乙個相同副本 另外,正文段...

C 程式的記憶體布局

乙個c c 源程式經過編譯之後,其應用程式使用的記憶體可劃分為一下幾個部分 1 區 區存放函式體的二進位制 可執行檔案載入之後,就存放在程序的 區。這部分分區域是唯讀的,如果試圖修改,將導致執行時錯誤。一般來說,程式的 區存放的是程式的可執行 在某些特殊情況下,一些重要的資料也可以放入 區,以防止錯...