ARM編譯空間屬性
一般情況下,一個(gè)程序本質(zhì)上都是由 bss段、data段、text段三個(gè)組成的——本概念是當(dāng)前的計(jì)算機(jī)程序設(shè)計(jì)中是很重要的一個(gè)基本概念。而且在嵌入式系統(tǒng)的設(shè)計(jì)中也非常重要,牽涉到嵌入式系統(tǒng)運(yùn)行時(shí)的內(nèi)存大小分配,存儲(chǔ)單元占用空間大小的問(wèn)題。
本文引用地址:http://butianyuan.cn/article/201611/319318.htmBSS段:BSS段(bss segment)通常是指用來(lái)存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域。BSS是英文Block Started by Symbol的簡(jiǎn)稱。BSS段屬于靜態(tài)內(nèi)存分配。
數(shù)據(jù)段:數(shù)據(jù)段(data segment)通常是指用來(lái)存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。
代碼段:代碼段(code segment/text segment)通常是指用來(lái)存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于只讀, 某些架構(gòu)也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等。
堆(heap):堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減)
text和data段都在可執(zhí)行文件中(在嵌入式系統(tǒng)里一般是固化在鏡像文件中),由系統(tǒng)從可執(zhí)行文件中加載。而bss段不在可執(zhí)行文件中,由系統(tǒng)初始化。
bss段(未手動(dòng)初始化的數(shù)據(jù))并不給該段的數(shù)據(jù)分配空間,只是記錄數(shù)據(jù)所需空間的大小。 data(已手動(dòng)初始化的數(shù)據(jù))段則為數(shù)據(jù)分配空間,數(shù)據(jù)保存在目標(biāo)文件中。 DATA段包含經(jīng)過(guò)初始化的全局變量以及它們的值。 BSS段的大小從可執(zhí)行文件中得到,然后鏈接器得到這個(gè)大小的內(nèi)存塊,緊跟在數(shù)據(jù)段后面。當(dāng)這個(gè)內(nèi)存區(qū)進(jìn)入程序的地址空間后全部清零。包含DATA和BSS段的整個(gè)區(qū)段此時(shí)通常稱為數(shù)據(jù)區(qū)。
2. ARM的image屬性
此處所說(shuō)的“ARM程序”是指在ARM系統(tǒng)中正在執(zhí)行的程序,而非保存在ROM中的bin映像(image)文件,這一點(diǎn)清注意區(qū)別。
一個(gè)ARM程序包含3部分:RO,RW和ZI
RO是程序中的指令和常量
RW是程序中的已初始化變量
ZI是程序中的未初始化的變量
Image文件包含了RO和RW數(shù)據(jù)。但不包含ZI數(shù)據(jù),是因?yàn)閆I數(shù)據(jù)都是0,沒(méi)必要包含,只要程序運(yùn)行之前將ZI數(shù)據(jù)所在的區(qū)域一律清零即可。包含進(jìn)去反而浪費(fèi)存儲(chǔ)空間。
燒錄到ROM中的image文件與實(shí)際運(yùn)行時(shí)的ARM程序之間并不是完全一樣的。因此就有必要了解ARM程序是如何從ROM中的image到達(dá)實(shí)際運(yùn)行狀態(tài)的。
實(shí)際上,RO中的指令至少應(yīng)該有這樣的功能:
1.
2.
ARM
ARM
ARM
.text段是代碼段。它用來(lái)放程序代碼(code)。它通常是只讀的(程序代碼,編譯好了就確定了,不可能改來(lái)改去的嘛)。
.data段是數(shù)據(jù)段。它用來(lái)存放初始化了的(initailized)全局變量(global)和初始化了的靜態(tài)變量(static)。它是可讀可寫的。
.bss段是全局變量數(shù)據(jù)段。它用來(lái)存放未初始化的(uninitailized)全局變量(global)和未初始化的靜態(tài)變量(static)。它也是可讀可寫的。bss是英文Block Started by Symbol的縮寫。之所以把bss跟data分開(kāi)來(lái),是因?yàn)橄到y(tǒng)會(huì)為這些bss段的變量的初值清零。
.constdata段是常量數(shù)據(jù)段。它用來(lái)存放常量(const)。它也是只讀的。
源程序中使用malloc分配的內(nèi)存就是bss這一塊,它的大小不是根據(jù)data的大小確定的,主要是由程序中同時(shí)分配內(nèi)存最大值所確定的,不過(guò)如果超出了范圍,也就是分配失敗,可以等空間釋放之后再分配。
以上這些段,用戶可以非常靈活的定義其首地址和大小。但對(duì)大部分用戶來(lái)說(shuō),程序代碼區(qū)在ROM或FLASH中,可讀寫區(qū)域在SRAM或DRAM中??紤]一下自己程序規(guī)模,函數(shù)調(diào)用規(guī)模,內(nèi)存使用大小,然后,參照一個(gè)連接定位文件,稍加修改就可以了
棧(stack)就是通常我們所說(shuō)的堆棧。它用來(lái)保存函數(shù)的局部變量和參數(shù)。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧,是一種“后進(jìn)先出”(Last In First Out,LIFO)的數(shù)據(jù)結(jié)構(gòu)。這意味著最后放到棧上的數(shù)據(jù),將會(huì)是第一個(gè)從棧上移走的數(shù)據(jù),對(duì)于哪些暫時(shí)存儲(chǔ)的信息,和不需要長(zhǎng)時(shí)間保存的信息來(lái)說(shuō),LIFO這種數(shù)據(jù)結(jié)構(gòu)非常理想。在調(diào)用函數(shù)或過(guò)程后,系統(tǒng)通常會(huì)清除棧上保存的局部變量、函數(shù)調(diào)用信息及其它信息。棧的頂部通常在可讀寫的RAM區(qū)的最后,其地址空間通常“向下減少”,即當(dāng)棧上保存的數(shù)據(jù)越多,棧的地址就越小。
堆(heap)就是通常我們說(shuō)的動(dòng)態(tài)內(nèi)存分配。它用來(lái)管理動(dòng)態(tài)內(nèi)存的。其操作方式跟數(shù)據(jù)結(jié)構(gòu)中的堆,是不同的。
在ARM的集成開(kāi)發(fā)環(huán)境中,
1、只讀的代碼段稱為Code段,即上述的.text段。
2、只讀的常量數(shù)據(jù)段,被稱作RO Data段,即上述的.constdata段。
以上兩個(gè)段統(tǒng)稱為RO段(Read Only),放在ROM或FLASH等非易失性器件中。
3、可讀可寫的初始化了的全局變量和靜態(tài)變量段,被稱作RW Data段(ReadWrite),即上述的.bss段。
4、可讀可寫的未初始化的全局變量和靜態(tài)變量段,被稱作ZI Data段(Zero Init),即上述的.data段。因?yàn)檫@個(gè)段里的變量要被初始化為零,所以叫ZI段。
以上兩個(gè)段統(tǒng)稱為RW段,而在運(yùn)行時(shí),它必須重新裝載到可讀可寫的RAM中。
評(píng)論