c 複習篇(二) 虛擬位址空間布局

2021-09-25 09:27:23 字數 1643 閱讀 5459

4g虛擬位址空間布局

其中1g是屬於核心空間,另外的3g屬於使用者空間

所有的程序都擁有屬於自己的使用者空間,但卻共享乙個核心空間。

①:128m大小的不可訪問區域(保留區)

我們通常將申請的臨時指標變數初始化時置為null,可以防止後續無意使用這個指標出錯,因為null == 0x0,將其指標指向0x0這個位址時,因為0x0這個位址屬於保留區,沒有訪問許可權的。

②:.text**段

這個區域儲存的是**中的指令。

指令:乙份**是由資料和指令構成的,除資料外剩下的都叫做指令,另外,區域性變數也屬於指令,但是區域性變數儲存在棧上,**執行時才在棧中預留好的區域中開闢。

③:.data資料段

這個區域儲存的是**中的各種資料,包括全域性變數,靜態區域性變數,但兩者必須為已初始化且初始化不為零的資料

④:.bss段

這個區域儲存也是**中的各種資料,不過儲存的是未初始化或者是初始化了但是為零的資料。

這個段其實在可執行檔案中不佔空間,(.bss段)在段表中儲存著,因為它記錄的都是一些未初始化的值要不就是初始化了但是為零的值,我們可以只記錄符號和符號所要占用的大小,在程式執行時,才進行開闢並將其空間全部清零。可以用readelf -s或者objdump -h 檢視

⑤:堆當我們需要申請一塊連續且指定大小的記憶體塊的動態記憶體時,需要在堆中申請。需要手動申請,手動釋放。不釋放會造成記憶體洩漏。(從低位址向高位址開闢)

⑥:棧所有區域性變數儲存在這裡,且函式的執行也需要棧的開闢,不過空間釋放由系統完成。(從高位址向低位址開闢)

⑦:命令列引數

int main()

//這是我們平常寫的main函式

其實它長這樣

int main(int argc, char *ar**,char *envp)

//這是真實的main函式

前兩個引數大家都很熟悉,argc是命令列引數的個數,不指定時預設為1,是當前檔名,char *ar** 也可以寫成char **ar**,其中ar**[0]預設儲存的就是argc == 1時的程式名。如果在執行程式時後面跟隨指令,則argc的值和ar**中的元素就會發生變化。

然而這第三個引數是什麼意思呢?在我們呼叫一些系統庫函式的時候,我們需要使用預處理指令#include。但是我們系統怎麼知道去哪個路徑尋找這些標頭檔案的函式定義呢?就是通過char *envp(環境變數)來實現的。

話說回來,命令列引數就是我們的ar**了。裡面存放著我們的程式名,以及引數(如果你給了的話)。

⑧:環境變數

就是在第⑦條中介紹的,main函式的第三個引數。

①:記憶體直接訪問(zone_dma(大約16mb))

全名zone_directmemoryaccess(直接記憶體訪問),可以加快磁碟和記憶體之間資料的交換,不需要經過cpu的暫存器,這時cpu可以去幹別的事,大大增加了效率。

②:zone_normal (大約892mb)

核心中最重要最常用的部分。用於直接對映。pcb就在這裡。

③:zone_highmem (128mb)

所謂的高階記憶體,用於在核心中對映高於1g的物理記憶體時使用。64位系統則沒有該段(根本不需要,因為64位作業系統給核心空間分配的記憶體達到512g)。

虛擬位址空間布局

在多工系統中,每個程序都執行在自己的虛擬位址空間上,32為模式下它是乙個4g的記憶體位址塊,在linux系統下主要分為1g核心空間和3g使用者空間,而在windows系統下,核心空間和使用者空間的劃分比例為2 2.位於虛擬位址空間最低部分為保留區,未賦予實體地址 text 為 段用來存放程式執行 d...

4G虛擬位址空間布局

一 其中,使用者程序部分分段儲存內容如下表所示 按位址遞增順序 名稱儲存內容 段 text 可執行 字串字面值 唯讀變數 資料段 data 已初始化且初始值為非0的全域性變數和靜態區域性變數 bss段 未初始化或初始值為0的全域性變數和靜態區域性變數 棧區域性變數 函式引數 返回位址等 堆動態分配的...

Linux X86 64位虛擬位址空間布局與試驗

在x86 64下面,其實虛擬位址只使用了48位。所以c程式裡,列印的位址都是只有12位16進製制。48位位址長度也就是對應了256tb的位址空間。而在linux下有效的位址區間是從0x00000000 00000000 0x00007fff ffffffff還有0xffff8000 00000000...