標籤:
BSS段:BSS段(bss segment)通常是指用來存放程式中未初始化的全域變數的一塊記憶體地區。BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體配置。
資料區段:資料區段(data segment)通常是指用來存放程式中已初始化的全域變數的一塊記憶體地區。資料區段屬於靜態記憶體配置。
程式碼片段:程式碼片段(code segment/text segment)通常是指用來存放程式執行代碼的一塊記憶體地區。這部分地區的大小在程式運行前就已經確定,並且記憶體地區通常屬於唯讀, 某些架構也允許程式碼片段為可寫,即允許修改程式。在程式碼片段中,也有可能包含一些唯讀常數變數,例如字串常量等。
堆(heap):堆是用於存放進程運行中被動態分配的記憶體段,它的大小並不固定,可動態擴張或縮減。當進程調用malloc等函數分配記憶體時,新分配的記憶體就被動態添加到堆上(堆被擴張);當利用free等函數釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)
棧(stack):棧又稱堆棧,是使用者存放程式臨時建立的局部變數,也就是說我們函數括弧“{}”中定義的變數(但不包括static聲明的變數,static意味著在資料區段中存放變數)。除此以外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,並且待到調用結束後,函數的傳回值也會被存放回棧中。由於棧的先進先出特點,所以棧特別方便用來儲存/恢複調用現場。從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時資料的記憶體區。
一個程式本質上都是由 bss段、data段、text段三個組成的。
這樣的概念,不知道最初來源於哪裡的規定,但在當前的電腦程式設計中是很重要的一個基本概念。而且在嵌入式系統的設計中也非常重要,牽涉到嵌入式系統運行時的記憶體大小分配,儲存單元佔用空間大小的問題。
在採用段式記憶體管理的架構中(比如intel的80x86系統),bss段(Block Started by Symbol segment)通常是指用來存放程式中未初始化的全域變數的一塊記憶體地區,一般在初始化時bss 段部分將會清零。bss段屬於靜態記憶體配置,即程式一開始就將其清零了。
比如,在C語言之類的程式編譯完成之後,已初始化的全域變數儲存在.data 段中,未初始化的全域變數儲存在.bss 段中。
在《Programming ground up》裡對.bss的解釋為:There is another section called the .bss. This section is like the data section, except that it doesn’t take up space in the executable.
text和data段都在可執行檔中(在嵌入式系統裡一般是固化在鏡像檔案中),由系統從可執行檔中載入;而bss段不在可執行檔中,由系統初始化。
1 前言
一直以來對於ARM體系中所描述的RO,RW和ZI資料存在似是而非的理解,這段時間對其仔細瞭解了一番,發現了一些規律,理解了一些以前書本上有的但是不理解的東西,我想應該有不少人也有和我同樣的困惑,因此將我的一些關於RO,RW和ZI的理解寫出來,希望能對大家有所協助。
要瞭解RO,RW和ZI需要首先瞭解以下知識。
2 ARM程式的組成
此處所說的“ARM程式”是指在ARM系統中正在執行的程式,而非儲存在ROM中的bin映像(image)檔案,這一點清注意區別。
一個ARM程式包含3部分:RO,RW和ZI
RO是程式中的指令和常量
RW是程式中的已初始設定變數
ZI是程式中的未初始化的變數
由以上3點說明可以理解為:
RO就是readonly,
RW就是read/write,
ZI就是zero
3 ARM映像檔案的組成
所謂ARM映像檔案就是指燒錄到ROM中的bin檔案,也成為image檔案。以下用Image檔案來稱呼它。
Image檔案包含了RO和RW資料。
之所以Image檔案不包含ZI資料,是因為ZI資料都是0,沒必要包含,只要程式運行之前將ZI資料所在的地區一律清零即可。包含進去反而浪費儲存空間。
Q:為什麼Image中必須包含RO和RW?
A:因為RO中的指令和常量以及RW中初始化過的變數是不能像ZI那樣“無中生有”的。
4 ARM程式的執行過程
從以上兩點可以知道,燒錄到ROM中的image檔案與實際運行時的ARM程式之間並不是完全一樣的。因此就有必要瞭解ARM程式是如何從ROM中的image到達實際運行狀態的。
實際上,RO中的指令至少應該有這樣的功能:
1. 將RW從ROM中搬到RAM中,因為RW是變數,變數不能存在ROM中。
2. 將ZI所在的RAM地區全部清零,因為ZI地區並不在Image中,所以需要程式根據編譯器給出的ZI地址及大小來將相應得RAM地區清零。ZI中也是變數,同理:變數不能存在ROM中
在程式啟動並執行最初階段,RO中的指令完成了這兩項工作後C程式才能正常訪問變數。否則只能運行不含變數的代碼。
BSS段 data段 text段 堆heap 和 棧stack