記憶體布局深度好文

2021-08-03 03:43:19 字數 1974 閱讀 9505

對任何乙個普通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偏移為正的都是被調函式的區域性變數。

離開位子,你是誰?(深度好文)

山上的寺院裡有一頭驢,每天都在磨房裡辛苦拉磨,天長日久,驢漸漸厭倦了這種平淡的生活。它每天都在尋思,要是能出去見見外面的世界,不用拉磨,那該有多好啊!不久,機會終於來了,有個僧人帶著驢下山去馱東西,它興奮不已。來到山下,僧人把東西放在驢背上,然後牽著它返回寺院。沒想到,路上行人看到驢時,都虔誠地跪在...

思維的八層境界(深度好文)

在世界快速變化的時代,思維是最重要的核心職業勝任力和職業競爭力。那麼,怎樣進行思考?怎樣提高自己的思維層次和水平?這個問題值得我們深思!所謂學問,就是對問題說得出道理,有自己的想法。想法似乎人人都是有的,但又等於沒有!用心想乙個問題,便會對這個問題有主見,形成自己的判斷。說是主見,稱之為偏見亦可。我...

思維的八層境界(深度好文)

在世界快速變化的時代,思維是最重要的核心職業勝任力和職業競爭力。那麼,怎樣進行思考?怎樣提高自己的思維層次和水平?這個問題值得我們深思!所謂學問,就是對問題說得出道理,有自己的想法。想法似乎人人都是有的,但又等於沒有!用心想乙個問題,便會對這個問題有主見,形成自己的判斷。說是主見,稱之為偏見亦可。我...