<一>關於進程虛擬地址空間區域內存劃分和布局

C++代碼在編譯完成後會生產.exe程序(windows平台), .EXE以文件的形式存儲在磁盤上,當運行.exe程序的時候
操作系統會將磁盤上的.exe文件加載到內存中,那麼在加載到內存中的時候,操作系統是如何在內存中存放這個exe程序的?
有沒有區域的劃分?那麼是如何劃分的?
首先需要了解一點,程序加載到內存中,是不能直接加載到物理內存中的

現在我們以 X86平台的Linux 環境舉例
當我們一個程序(進程)在啟動執行時,操作系統會為其分配一個4G(2的32次方)的內存空間(就是進程的虛擬內存地址空間)

如下圖內存分配圖

點擊查看代碼
#incclude <iostrea>
using namespace std;

int gdata1=1;
int gdata2=0;
int gdata3;

static int gdata4=10;
static int gdata5=0;
static int gdata6;
int main(){
	
	int a=100;
	int b=0;
	int c;
	
	static  int d=1000;
	static  int e=0;
	static  int f;	
	return 0;	
}

如上面代碼中的全局變量
gdata1,gdata2,gdata3,gdata4,gdata5,gdata6
無論是普通的還是靜態的,他們都叫”數據”,每一個數據在編譯後,在符號表中都會產生符號.
gdata1和gdata4 初始化了的,而且值部不為0,所以存儲在.data段
gdata2和gdata5 初始化了,但是值為0,所以存儲在.bss段
gdata3和gdata6 未初始化,存儲在.bss段

main 函數中的 a,b,c 不是數據,不會在符號表中產生符號,他們編譯只產生指令
例如:move dword prt[a], och ,他們是存儲在.text段,當程序運行到這裡時,他們是在棧上分配空間的

對於靜態的局部變量 如 d,e,f 也是數據,存放在數據段,也會在符號表中產生符號,
程序啟動的時候不會初始化,而是在第一次運行到的時候才會初始化, d存儲在.data段,e,f存儲在.bss段

打印C的值,是一個棧上的隨機值,打印f,由於存儲在.bss段,系統會負責為.bss段做初始化,置0,所以打印出來f為0

上面紅框部分存儲在代碼段,藍色框部分存儲在數據段

注意:不同的進程之間,用戶空間是私有的,內核空間是共享的

Tags: