源地址:http://www.cnblogs.com/fengyv/p/3789252.html
侵刪汞窗。
一個程序本質(zhì)上都是由 BSS 段、data段、text段三個組成的北苟。
- BSS段:在采用段式內(nèi)存管理的架構(gòu)中,BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域怕篷。BSS是英文Block Started by Symbol的簡稱历筝。BSS段屬于靜態(tài)內(nèi)存分配。
- 數(shù)據(jù)段:在采用段式內(nèi)存管理的架構(gòu)中廊谓,數(shù)據(jù)段(data segment)通常是指用來存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域梳猪。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。
- 代碼段:在采用段式內(nèi)存管理的架構(gòu)中蒸痹,代碼段(text segment)通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域春弥。這部分區(qū)域的大小在程序運行前就已經(jīng)確定,并且內(nèi)存區(qū)域?qū)儆谥蛔x叠荠。在代碼段中匿沛,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等榛鼎。
程序編譯后生成的目標(biāo)文件至少含有這三個段逃呼,這三個段的大致結(jié)構(gòu)圖如下所示:
其中.text即為代碼段,為只讀者娱。.bss段包含程序中未初始化的全局變量和static變量抡笼。data段包含三個部分:heap(堆)、stack(棧)和靜態(tài)數(shù)據(jù)區(qū)黄鳍。
- 堆(heap):堆是用于存放進程運行中被動態(tài)分配的內(nèi)存段蔫缸,它的大小并不固定,可動態(tài)擴張或縮減际起。當(dāng)進程調(diào)用malloc等函數(shù)分配內(nèi)存時拾碌,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴張);當(dāng)利用free等函數(shù)釋放內(nèi)存時街望,被釋放的內(nèi)存從堆中被剔除(堆被縮減)
- 棧 (stack):棧又稱堆棧校翔, 是用戶存放程序臨時創(chuàng)建的局部變量,也就是說我們函數(shù)括弧“{}”中定義的變量(但不包括static聲明的變量灾前,static意味著在數(shù)據(jù)段中存放變量)防症。除此以外,在函數(shù)被調(diào)用時哎甲,其參數(shù)也會被壓入發(fā)起調(diào)用的進程棧中蔫敲,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會被存放回棧中炭玫。由于棧的先進先出特點奈嘿,所以棧特別方便用來保存/恢復(fù)調(diào)用現(xiàn)場從這個意義上講,我們可以把堆椡碳樱看成一個寄存裙犹、交換臨時數(shù)據(jù)的內(nèi)存區(qū)尽狠。
當(dāng)程序在執(zhí)行時動態(tài)分配空間(C中的malloc函數(shù)),所分配的空間就屬于heap叶圃。其概念與數(shù)據(jù)結(jié)構(gòu)中“堆”的概念不同袄膏。
stack段存放函數(shù)內(nèi)部的變量、參數(shù)和返回地址掺冠,其在函數(shù)被調(diào)用時自動分配沉馆,訪問方式就是標(biāo)準(zhǔn)棧中的LIFO方式。(因為函數(shù)的局部變量存放在此德崭,因此其訪問方式應(yīng)該是棧指針加偏移的方式斥黑,否則若通過push、pop操作來訪問相當(dāng)麻煩)
data段中的靜態(tài)數(shù)據(jù)區(qū)存放的是程序中已初始化的全局變量接癌、靜態(tài)變量和常量。
在采用段式內(nèi)存管理的架構(gòu)中(比如intel的80x86系統(tǒng))扣讼,BSS 段(Block Started by Symbol segment)通常是指用來存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域缺猛,一般在初始化時 BSS 段部分將會清零。BSS 段屬于靜態(tài)內(nèi)存分配椭符,即程序一開始就將其清零了荔燎。
比如,在C語言之類的程序編譯完成之后销钝,已初始化的全局變量保存在.data 段中有咨,未初始化的全局變量保存在.bss 段中。
text和data段都在可執(zhí)行文件中(在嵌入式系統(tǒng)里一般是固化在鏡像文件中)蒸健,由系統(tǒng)從可執(zhí)行文件中加載座享;而BSS段不在可執(zhí)行文件中,由系統(tǒng)初始化似忧。
BSS段只保存沒有值的變量渣叛,所以事實上它并不需要保存這些變量的映像。運行時所需要的BSS段大小記錄在目標(biāo)文件中盯捌,但BSS段并不占據(jù)目標(biāo)文件的任何空間淳衙。
//main.c
int a = 0; //全局初始化區(qū)
char *p1; //全局未初始化區(qū)
main()
{
static int c =0; //全局(靜態(tài))初始化區(qū)
int b; //棧
char s[] = "abc"; //棧
char *p2; //棧
char *p3 = "123456"; //"123456\0"在常量區(qū)饺著,p3在棧上箫攀。
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); //分配得來得10和20字節(jié)的區(qū)域就在堆區(qū)。
}