編譯鏈結執行原理 虛擬位址空間布局

2021-08-31 03:54:50 字數 1588 閱讀 8434

1、早期記憶體分配機制

在早期的計算機中,要執行乙個程式,會把這些程式全都裝入記憶體,程式都是直接執行在記憶體上的,也就是說程式中訪問的記憶體位址都是實際的物理記憶體位址。當計算機同時執行多個程式時,必須保證這些程式用到的記憶體總量要小於計算機實際物理記憶體的大小。但是同時存在以下3個問題:1、程序位址空間不隔離。由於程式都是直接訪問物理記憶體,所以惡意程式可以隨意修改別的程序的記憶體資料,以達到破壞的目的。2、記憶體使用效率低3、程式執行的位址不確定。

為了解決上述問題,人們想到了一種變通的方法,就是增加乙個中間層,利用一種間接的位址訪問方法訪問物理記憶體。按照這種方法,程式中訪問的記憶體位址不再是實際的物理記憶體位址,而是乙個虛擬位址,然後由作業系統將這個虛擬位址對映到適當的物理記憶體位址上。這樣,只要作業系統處理好虛擬位址到物理記憶體位址的對映,就可以保證不同的程式最終訪問的記憶體位址位於不同的區域,彼此沒有重疊,就可以達到記憶體位址空間隔離的效果。當建立乙個程序時,作業系統會為該程序分配乙個4gb大小的虛擬程序位址空間,注意這個4gb的位址空間是「虛擬」的,並不是真實存在,而每個程序只能訪問自己虛擬位址空間中的資料,無法訪問別的程序中的資料,通過這種方法實現了程序間的隔離。之所以為4gb,是因為在32位的作業系統中,乙個指標長度是4位元組,而4位元組指標的定址能力是從0x0000 0000~0xffff ffff,最大值0xffff ffff表示的即為4gb大小的容量。

linux程序虛擬位址空間,總位址空間按3:1的比例劃分,使用者態佔3g,核心占用了1g。各程序的使用者虛擬位址空間起始於0,到0xc000 0000的位置,其上為核心位址空間。

2、使用者態位址空間

(1).reserve保留區 

一共占用128m,屬於預留空間,程序是不允許被訪問的。

(2).text(**段) 

存放指令,一般是共享的,編譯時確定,唯讀,不允許修改。

(3).data 

存放已初始化且初始化不為0的資料(編譯階段(而非執行時)就能確定的資料,可讀可寫,賦了初值的全域性變數和賦初值的靜態變數,常量也存放在這個區域)也就是通常所說的靜態儲存區。

(4).bss段 

用來存放程式中未初始化以及初始化為0的全域性/靜態變數的一塊記憶體區域,在elf檔案中,該區域的變數僅僅是乙個符號並不占用檔案空間,但程式載入後,會占用記憶體空間,並初始化為0。

(5).heap(堆) 

用於存放程序執行時動態開闢的記憶體,通過malloc/new可以申請記憶體,free/delete用來釋放記憶體,heap的位址從低向高擴充套件,是不連續的空間。

(6)共享庫(mmap)

共享庫及匿名檔案的對映區域;該區域包含共享庫的**段和資料段。其中**段共享,資料段私有,寫時拷貝。增長方式從高位址向地位址增長。

(7).stack(棧) 

(8)命令列引數

(9)環境變數

3、核心位址空間

(1)zone_dmn直接訪問

包含低於16mb的記憶體頁框,存放核心**和資料,資料直接從資料匯流排拿。

(2)zone_normal常用部分

包含高於16mb低於896mb的記憶體頁框

(3)高階記憶體

程式編譯鏈結,執行原理,虛擬位址空間布局

1 預編譯過程 i 1.刪除 define文字替換 2.if endif elif 3.include遞迴展開 4.刪除注釋 5.新增行號 主要目的是為了方便除錯 6.保留 pragma 2 編譯 s 1.詞法分析 例 int 8a 10 變數不能以數字開頭 2.語法分析 根據一條表示式分析 3.語...

c 編譯鏈結執行原理及虛擬位址空間布局

當我們寫好.c cpp檔案時 此時檔案還不能執行 因為他要經過以下的四步才可以執行 c cpp 生成.i 編譯 生成.s 彙編 生成.o 鏈結 生成.exe 1.define巨集替換 1.詞法分析 指令翻譯成二進位制 1.合併段和符號表 2.include 遞迴展開 2.語法分析 2.符號解析 3....

C 虛擬位址空間與編譯鏈結原理

1.虛擬位址空間 程序位址空間需要隔離,防止惡意的程式修改其它程式的記憶體資料,因此計算機中引入虛擬位址空間。虛擬位址空間布局 text 段 可執行 唯讀變數 字串常量 data 資料段 已初始化且初值非0的全域性變數和靜態變數 全域性和區域性 bss 未初始化或初始值為0的全域性變數和靜態變數。如...