c 程序記憶體分段以及分段的目的

2021-09-10 07:25:12 字數 2306 閱讀 8875

棧區

int x = 0; int *p = null;

堆區

int *p = new int[20];

全域性區

儲存全域性變數及靜態變數

常量區

儲存常量和字串;

string str = "hello";

**區

儲存邏輯**的二進位制

記憶體分割槽

將資料和**分開的好處有三點:

第一,可以為他們賦予不同的屬性。

比如資料本身是需要修改的,所以資料就需要有可寫的屬性,不讓資料段可寫,那程式根本就無法執行啦。程式中的**是不能被更改的,這樣就要求**段具備唯讀的屬性。真要是在執行過程中程式的下一條指令被修改了,誰知道會會產生什麼樣的災難。

第二,為了提高cpu內部快取的命中率。

大夥兒知道,快取起作用的原因是程式的區域性性原理。在cpu內部也有快取機制,將程式中的指令和資料分離,這有利於增強程式的區域性性。因此cpu內部有針對資料和針對指令的兩種快取機制,因此,將資料和**分開儲存將使程式執行更快。

第三,節省記憶體。

程式中存在一些唯讀的部分,比如**,當乙個程式的多個副本同時執行時(比如同時執行多個ls命令時),沒必要在記憶體中同時存在多個相同的**段,這將浪費有限的物理記憶體資源,只要把這乙個**段共享就可以了。

後兩點較容易理解,咱們深入討論下第一點,不知您有沒有想過,資料段或**段的屬性是誰給新增上的呢,是誰又去根據屬性保護程式的呢,是程式設計師嗎?是編譯器嗎?是作業系統嗎?還是cpu一級的硬體支援

1.這些劃分是編譯器幫我們做的,編譯器先幫我們劃分一下段,只是劃分,不做別的處理

2.再看cpu為我們提供了哪些原生的支援。在保護模式下,有這樣乙個資料結構,它叫gdt(global descriptor table)全域性描述符表,這個表中的每一項稱為段描述符。先學習一下,什麼是描述符?描述符就是描述某種資料的資料結構,是元資訊,屬於資料的資料。就像人們的身份證,上面有寫性別,出生日期,位址等描述個人情況的資訊。在段描述符中有段的屬性位,在以後的章節中可以看到,其實是有2個,乙個是s欄位,佔1bit大小,另外乙個是佔4bit大小的type欄位,這兩個字段配合在一起使用就能組合出各種屬性,如:唯讀,向下擴充套件,只執行等等。提供歸提供,可得有人去填寫這張表啊,誰來做這事呢,作業系統。

3。作業系統在讓cpu進入保護模式之前,首先要準備好gdt,也就是要設定好gdt的相關項,填寫好段描述符。段描述符填寫成什麼樣,段具備什麼樣的屬性,這完全取決於作業系統了,在這裡大家只要知道,段描述符中的s欄位和type欄位負責該段的屬性,也就是該屬性與安全相關。

說到這裡,答案似乎浮出水面了:

編譯器負責挑選出哪些資料具備怎樣的屬性,從而根據屬性將程式片段分類,比如,劃分出了唯讀屬性的**段和可寫屬性的資料段。再補充一下,編譯器並沒有讓段具備某種屬性,對於**段,編譯器所做的只是將**歸類到一起而已,也就是將程式中的有關**的多個section合併成乙個大的segment(這就是我們所說的**段),它並沒有為**段新增額外的資訊。作業系統通過設定gdt全域性描述符表來構建段描述符,在段描述符中指定段的位置、大小及屬性(包括s欄位和type欄位)。也就是說,作業系統認為**應該是唯讀的,所以給用來指向**段的那個段描述符設定了唯讀的屬性,這才是真正給段新增屬性的地方。cpu中的段暫存器提前被作業系統賦予相應的選擇子,從而確定了指向的段。在執行指令時,會根據該段的屬性來判斷指令的行為,若有返回則發出異常。

總之,編譯器,作業系統,cpu三個配合在一起才能對程式保護,檢測出指令中的違規行為。如果gdt中的**段描述符具備可寫的屬性,那編譯器再怎麼劃分**段都沒有用,有判斷權利的只有cpu。

這個分段和作業系統記憶體管理中的分段機制有關係嗎?

我想大家應該已經搞清楚了記憶體分段和程式分段的關係,其實就是一回事,記憶體分段指的是處理器為訪問記憶體而採用的機制,稱之為記憶體分段機制,程式分段是軟體中人為邏輯劃分的記憶體區域(編譯器、作業系統合力完成的),它本身也是記憶體,所以處理器在記憶體管理時,也會採用記憶體分段機制,用段暫存器指向該區域的起始位址,即把人為劃分的段作為記憶體訪問中劃分的段。

arm linux記憶體分段的分析

4gb的空間分段管理,每段1mb,共4k段,顯然每段需要一定記憶體開銷來描述該 段虛擬位址到實體地址的對映及該段的其他特性。規定以4位元組來描述每段,則4k段需要4k 4 16kb位元組的開銷來描述整個記憶體分 段的特性.我們把這連續的16kb位元組稱為頁表,如下圖所示.其中每行的4位元組稱為乙個頁...

記憶體的分段 分頁機制

摘錄自 程式設計師的自我修養 1.5節 早期的計算機中,記憶體有限,在執行多個程式時有如下問題 1.位址空間不隔離 程式直接訪問物理記憶體,程式間互相影響 2.記憶體使用效率低 需要將整個程式載入記憶體,程式切換時候,在記憶體和磁碟間交換效率低下 3.程式執行位址不確定 因為直接訪問物理記憶體,使用...

C 繼承體系中的記憶體分段

綜述與目錄 討論這個問題之前我們先明確類的結構,乙個類的大概組成,下面的很多分類名詞都是我個人杜撰,為的就是讓讀者看懂能夠區分,下面分別分類 目錄 空類不含任何成員變數,也不繼承某個基類。結構類像c語言中結構體一樣,要麼只包含基本資料型別,要麼是其他構造型別的巢狀,或者兩者兼而有之。派生類有至少乙個...