在多工系統中,每個程序都執行在自己的虛擬位址空間上,32為模式下它是乙個4g的記憶體位址塊,在linux系統下主要分為1g核心空間和3g使用者空間,而在windows系統下,核心空間和使用者空間的劃分比例為2:2.
位於虛擬位址空間最低部分為保留區,未賦予實體地址
.text 為**段用來存放程式執行**
.data段稱為資料段,用來存放程式中已初始化並且初始化不為0的全域性變數和靜態區域性變數,資料段屬於靜態記憶體分配,可讀可寫
.bss段又稱未初始化段,用來存放未初始化或者初始化為0的全域性變數和靜態區域性變數
資料段與bss段的區別如下:
1) bss段不占用物理檔案尺寸,但占用記憶體空間;資料段占用物理檔案,也占用記憶體空間。
對於大型陣列如int ar0[10000] = 和int ar1[10000],ar1放在bss段,只記錄共有10000*4個位元組需要初始化為0,而不是像ar0那樣記錄每個資料1、2、3...,此時bss為目標檔案所節省的磁碟空間相當可觀。
2) 當程式讀取資料段的資料時,系統會出發缺頁故障,從而分配相應的物理記憶體;當程式讀取bss段的資料時,核心會將其轉到乙個全零頁面,不會發生缺頁故障,也不會為其分配相應的物理記憶體。
執行時資料段和bss段的整個區段通常稱為資料區。某些資料中「資料段」指代資料段 + bss段 + 堆。
.heap段用於存放程序執行時動態分配的記憶體段,可動態擴張或縮減。堆中內容是匿名的,不能按名字直接訪問,只能通過指標間接訪問。當程序呼叫malloc(c)/new(c++)等函式分配記憶體時,新分配的記憶體動態新增到堆上(擴張);當呼叫free(c)/delete(c++)等函式釋放記憶體時,被釋放的記憶體從堆中剔除(縮減) 。
.stack又稱堆疊,由編譯器自動分配釋放,行為類似資料結構中的棧(先進後出)
主要有三個用途:
(1)為函式內部宣告的非靜態區域性變數提供儲存空間
(2)記錄函式呼叫過程中相關的維護性資訊
(3)臨時儲存區,用於暫存長算式表示式部分計算結果或alloca()函式分配的棧內記憶體
linux中可以用ulimit -s命令來檢視和設定堆疊最大值,
函式堆疊呼叫開棧過程:
(1).壓入實參 自右向左
(3).壓呼叫方函式的棧底位址
(4).跳轉到被呼叫方函式的棧幀
(5).開闢被呼叫方函式執行需要的棧空間
呼叫約定
_cdecl c標準呼叫約定
_stdcall windows下標準呼叫約定
_fastcall 快速呼叫約定
_thiscall 類成員方法呼叫約定
各約定不同點:
1.函式的符號生成
2.實參的入棧順序
3.形參的開闢和清理
_cdecl 呼叫方 呼叫方
_stdcall 呼叫方 被呼叫方
_fastcall 呼叫方 被呼叫方
4G虛擬位址空間布局
一 其中,使用者程序部分分段儲存內容如下表所示 按位址遞增順序 名稱儲存內容 段 text 可執行 字串字面值 唯讀變數 資料段 data 已初始化且初始值為非0的全域性變數和靜態區域性變數 bss段 未初始化或初始值為0的全域性變數和靜態區域性變數 棧區域性變數 函式引數 返回位址等 堆動態分配的...
c 複習篇(二) 虛擬位址空間布局
4g虛擬位址空間布局 其中1g是屬於核心空間,另外的3g屬於使用者空間 所有的程序都擁有屬於自己的使用者空間,但卻共享乙個核心空間。128m大小的不可訪問區域 保留區 我們通常將申請的臨時指標變數初始化時置為null,可以防止後續無意使用這個指標出錯,因為null 0x0,將其指標指向0x0這個位址...
Linux X86 64位虛擬位址空間布局與試驗
在x86 64下面,其實虛擬位址只使用了48位。所以c程式裡,列印的位址都是只有12位16進製制。48位位址長度也就是對應了256tb的位址空間。而在linux下有效的位址區間是從0x00000000 00000000 0x00007fff ffffffff還有0xffff8000 00000000...