嵌入式 程序中的text段、data段和bss段

一般情況,一個程序本質上都是由 bss段、data段、text段三個段組成——這是計算機程序設計中重要的基本概念。而且在嵌入式系統的設計中也非常重要,牽涉到嵌入式系統運行時的內存大小分配,存儲單元佔用空間大小的問題。

在採用段式內存管理的架構中(比如intel的80x86系統),bss段(Block Started by Symbol segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域,一般在初始化時bss 段部分將會清零(bss段屬於靜態內存分配,即程序一開始就將其清零了)。

 

比如,在C語言程序編譯完成之後,已初始化的全局變量保存在.data 段中,未初始化的全局變量保存在.bss 段中。

 

 

text段: 用於存放程序代碼的區域, 編譯時確定, 只讀。更進一步講是存放處理器的機器指令,當各個源文件單獨編譯之後生成目標文件,經連接器鏈接各個目標文件並解決各個源文件之間函數的引用,與此同時,還得將所有目標文件中的.text段合在一起,但不是簡單的將它們“堆”在一起就完事,還需要處理各個段之間的函數引用問題。

 

在嵌入式系統中,如果處理器是帶MMU(MemoryManagement Unit,內存管理單元),那麼當我們的可執行程序被加載到內存以後,通常都會將.text段所在的內存空間設置爲只讀,以保護.text中的代碼不會被意外的改寫(比如在程序出錯時)。當然,如果沒有MMU就無法獲得這種代碼保護功能。

 

data段 :用於存放在編譯階段(而非運行時)就能確定的數據,可讀可寫。也是通常所說的靜態存儲區,賦了初值的全局變量、常量和靜態變量都存放在這個域。

 

而bss段不在可執行文件中,由系統初始化。

 

關於data和bss段更詳細的區別我們不妨用下面2段小程序說明一下

 

程序1:

int ar[30000];

void main()

{

......

}

 

程序2:

int ar[300000] = {1, 2, 3, 4, 5, 6 };

void main()

{

......

}

 

發現程序2編譯之後所得的可執行文件比程序1大得多。

 

爲什麼?

 

區別很明顯,程序1位於bss段,程序2位於data段,兩者的區別在於:

 

全局的未初始化變量存在於bss段中,具體體現爲一個佔位符,全局的已初始化變量存於data段中,而函數內的自動變量都在棧上分配空間。

 

bss不佔用可執行文件空間,其內容由操作系統初始化(清零),裸機程序需要自行手動清零。

 

而data段則需要佔用可執行文件空間,其內容由程序初始化,因此造成了上述情況。

 

注意

 

bss段(未手動初始化的數據)並不給該段的數據分配空間,只是記錄數據所需空間的大小。

 

data段(已手動初始化的數據)爲數據分配空間,數據保存在目標文件中。

 

data段包含經過初始化的全局變量以及它們的值。

 

BSS段的大小從可執行文件中得到,然後鏈接器得到這個大小的內存塊,緊跟在數據段後面。當這個內存區進入程序的地址空間後全部清零,包含data和bss段的整個區段此時通常稱爲數據區。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章