新聞中心

ARM編譯空間屬性

作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
1. 程序的空間屬性

一般情況下,一個程序本質(zhì)上都是由 bss段、data段、text段三個組成的——本概念是當(dāng)前的計算機程序設(shè)計中是很重要的一個基本概念。而且在嵌入式系統(tǒng)的設(shè)計中也非常重要,牽涉到嵌入式系統(tǒng)運行時的內(nèi)存大小分配,存儲單元占用空間大小的問題。

本文引用地址:http://m.butianyuan.cn/article/201611/319318.htm

BSS段: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)存從堆中被剔除(堆被縮減)

棧(stack):棧又稱堆棧,是用戶存放程序臨時創(chuàng)建的局部變量,也就是說我們函數(shù)括弧“{}”中定義的變量(但不包括static聲明的變量,static意味著在數(shù)據(jù)段中存放變量)。除此以外,在函數(shù)被調(diào)用時,其參數(shù)也會被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會被存放回棧中。由于棧的先進(jìn)先出特點,所以棧特別方便用來保存/恢復(fù)調(diào)用現(xiàn)場。從這個意義上講,我們可以把堆??闯梢粋€寄存、交換臨時數(shù)據(jù)的內(nèi)存區(qū)。

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程序”是指在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.將RW從ROM中搬到RAM中,因為RW是變量,變量不能存在ROM中。
2.將ZI所在的RAM區(qū)域全部清零,因為ZI區(qū)域并不在Image中,所以需要程序根據(jù)編譯器給出的ZI地址及大小來將相應(yīng)得RAM區(qū)域清零。ZI中也是變量,同理:變量不能存在ROM中在程序運行的最初階段,RO中的指令完成了這兩項工作后C程序才能正常訪問變量。否則只能運行不含變量的代碼。
ARMC中的指令以及常量被編譯后是RO類型數(shù)據(jù)。
ARMC中的未被初始化或初始化為0的變量編譯后是ZI類型數(shù)據(jù)。
ARMC中的已被初始化成非0值的變量編譯后市RW類型數(shù)據(jù)。

.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中。




關(guān)鍵詞: ARM編譯空間屬

評論


技術(shù)專區(qū)

關(guān)閉