這幾天在看c語言的書籍,對c的記憶體映像有點疑惑,於是,查詢資料,查閱了龐麗萍編著的《作業系統原理》第四版中的第七章主存管理中的段式系統,此外還看了王元珍、曹忠生、韓忠芬編著的《80x86組合語言程式設計》得到了乙個自己對在80x86結構下的記憶體對映的理解。不過也許自己的理解是錯的或者有不到之處,希望大神能夠指出理解的不足之處。
首先,乙個c程式,在記憶體中的對映(當然這裡指的是80x86系統)包括四個區域(這裡是在看c語言大全的時候介紹的):
第乙個區域是程式**區域:存放的是程式**。
第二個區域是全域性變數區域:存放的是全域性變數和靜態變數等伴隨著整個程式生存過程的資料。
第四個區域是堆(heap):用來提供給程式設計師動態分配和釋放的區域,比如使用malloc申請一段記憶體,就是在這個區域中申請的。
然後聯絡《80x86組合語言程式設計》中介紹的intel80x86微處理器結構中暫存器的知識,知道在處理器中的六大部件中,暫存器分為以下幾個:
執行部件中的暫存器:
eax:累加暫存器
ebx:基址暫存器
ecx:計數暫存器
edx:資料暫存器
esi:源變址暫存器
edi:目的變址暫存器
指令預取部件中的暫存器:
eip:指令指示暫存器,存放的是下一條將要被cpu執行的指令的偏移位址(ea),它的值為該指令到所在段首位址的位元組距離。
分段部件中的暫存器:
cs:**段暫存器
ss:堆疊段暫存器
ds:資料段暫存器
聯絡兩者的關係,我們可以這樣認為:
c程式記憶體對映中的程式**區域對應的是cs(**段暫存器)中描述的虛擬記憶體區域;
c程式記憶體對映中的全域性變數區域對應的是ds(資料段暫存器)中描述的虛擬記憶體區域;
c程式記憶體對映中的堆(heap)和棧(stack)對應的是ss(堆疊段暫存器)中描述的虛擬記憶體區域,其中堆(heap)從該段中的高低址向低位址分配,棧(stack)從該段中的低位址向高低址分配,兩者公用乙個段。
那麼,我們如何通過分段部件中的暫存器cs、ss、ds來得到我們的記憶體位址呢。如何確定ss堆疊段中的起始位址和終止位址呢。這就要查閱《作業系統原理》中關於主存管理中的段式系統了。
在段式系統中,將主存分為很多個分割槽,每乙個段佔乙個分割槽,對於乙個段來說,它有自己的名字,是乙個連續的位址區。在段式系統中,邏輯分段由**分段、資料分段、棧段組成。剛好對應著上面**段暫存器、堆疊段暫存器、資料段暫存器。使用者通過給出段名(cs、ss、ds中的內容)和段內偏移位址(e**暫存器中的內容)來訪問這些段(實際上,作業系統會用唯一的段號來替代該段的段名)。所以,一般的程式位址形式由(s,w)組成,s是段號,w是段內偏移位址。而段式位址變換由段表來實現,段表如下所示:段表
段號長度基址0
...slb
1、取出程式位址(s,w)
2、用s檢索段表
3、判斷主存是否越界(請看儲存保護)
4、b+w即為所需要的主存位址
總結:所以我們通過cpu中分段部件中的暫存器cs、ds、ss中的內容來檢索段表,找到段表中的對應資訊,得到c程式中的記憶體對映區域。然後根據e**暫存器中存放的偏移位址,來確定我們需要的c程式對映記憶體中的乙個儲存單元位址。並且可以根據段表得到記憶體區域的起始位址和終止位址。
程式的記憶體映像
一 程式的記憶體映像 乙個由c c 編譯的程式的記憶體分布分為以下幾個部分 1 棧 stack 也是我們所說的堆疊,是由編譯器自動分配釋放,用來存放函式引數值,函式的返回位址,非靜態區域性變數的值等。其操作方式類似於資料結構中的棧 後進先出 lifo 2 堆 heep 一般由程式設計師分配釋放,若程...
linux c的記憶體映像
記憶體映像其實就是在記憶體中建立乙個和外存檔案完全相同的映像。使用者可以將整個檔案對映到記憶體中也可以部分對映到記憶體。系統會將對記憶體映像的改動如實的反映到外存檔案中。從而實現了通過記憶體映像對外存檔案的操作。記憶體映像的特點 1 可以加快對io的操作速度。2 使用者可以通過指針對檔案進行操作,間...
c 的記憶體映像
先來看乙個問題 類的空指標能不能呼叫類的成員函式呢?class a a void func 1 為什麼會有這種情況呢接下來我們看看c 的物件記憶體映像 下圖是a的物件的記憶體布局 a這種基本的c 物件模型有下述幾個規則 因此,構成物件本身的只有資料,任何成員函式都不隸屬於任何乙個物件,非靜態成員函式...