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