新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM編譯空間屬性

        ARM編譯空間屬性

        作者: 時間:2016-11-21 來源:網絡 收藏
        1. 程序的空間屬性

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

        本文引用地址:http://www.104case.com/article/201611/319318.htm

        BSS段:BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域。BSS是英文Block Started by Symbol的簡稱。BSS段屬于靜態內存分配。

        數據段:數據段(data segment)通常是指用來存放程序中已初始化的全局變量的一塊內存區域。數據段屬于靜態內存分配。

        代碼段:代碼段(code segment/text segment)通常是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經確定,并且內存區域通常屬于只讀, 某些架構也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。

        堆(heap):堆是用于存放進程運行中被動態分配的內存段,它的大小并不固定,可動態擴張或縮減。當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)

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

        text和data段都在可執行文件中(在嵌入式系統里一般是固化在鏡像文件中),由系統從可執行文件中加載。而bss段不在可執行文件中,由系統初始化。

        bss段(未手動初始化的數據)并不給該段的數據分配空間,只是記錄數據所需空間的大小。 data(已手動初始化的數據)段則為數據分配空間,數據保存在目標文件中。 DATA段包含經過初始化的全局變量以及它們的值。 BSS段的大小從可執行文件中得到,然后鏈接器得到這個大小的內存塊,緊跟在數據段后面。當這個內存區進入程序的地址空間后全部清零。包含DATA和BSS段的整個區段此時通常稱為數據區。

        2. ARM的image屬性

        ARM程序的組成
        此處所說的“ARM程序”是指在ARM系統中正在執行的程序,而非保存在ROM中的bin映像(image)文件,這一點清注意區別。
        一個ARM程序包含3部分:RO,RW和ZI
        RO是程序中的指令和常量
        RW是程序中的已初始化變量
        ZI是程序中的未初始化的變量
        Image文件包含了RO和RW數據。但不包含ZI數據,是因為ZI數據都是0,沒必要包含,只要程序運行之前將ZI數據所在的區域一律清零即可。包含進去反而浪費存儲空間。

        燒錄到ROM中的image文件與實際運行時的ARM程序之間并不是完全一樣的。因此就有必要了解ARM程序是如何從ROM中的image到達實際運行狀態的。
        實際上,RO中的指令至少應該有這樣的功能:
        1.將RW從ROM中搬到RAM中,因為RW是變量,變量不能存在ROM中。
        2.將ZI所在的RAM區域全部清零,因為ZI區域并不在Image中,所以需要程序根據編譯器給出的ZI地址及大小來將相應得RAM區域清零。ZI中也是變量,同理:變量不能存在ROM中在程序運行的最初階段,RO中的指令完成了這兩項工作后C程序才能正常訪問變量。否則只能運行不含變量的代碼。
        ARMC中的指令以及常量被編譯后是RO類型數據。
        ARMC中的未被初始化或初始化為0的變量編譯后是ZI類型數據。
        ARMC中的已被初始化成非0值的變量編譯后市RW類型數據。

        .text段是代碼段。它用來放程序代碼(code)。它通常是只讀的(程序代碼,編譯好了就確定了,不可能改來改去的嘛)。

        .data段是數據段。它用來存放初始化了的(initailized)全局變量(global)和初始化了的靜態變量(static)。它是可讀可寫的。

        .bss段是全局變量數據段。它用來存放未初始化的(uninitailized)全局變量(global)和未初始化的靜態變量(static)。它也是可讀可寫的。bss是英文Block Started by Symbol的縮寫。之所以把bss跟data分開來,是因為系統會為這些bss段的變量的初值清零。

        .constdata段是常量數據段。它用來存放常量(const)。它也是只讀的。

        源程序中使用malloc分配的內存就是bss這一塊,它的大小不是根據data的大小確定的,主要是由程序中同時分配內存最大值所確定的,不過如果超出了范圍,也就是分配失敗,可以等空間釋放之后再分配。

        以上這些段,用戶可以非常靈活的定義其首地址和大小。但對大部分用戶來說,程序代碼區在ROM或FLASH中,可讀寫區域在SRAM或DRAM中。考慮一下自己程序規模,函數調用規模,內存使用大小,然后,參照一個連接定位文件,稍加修改就可以了

        棧(stack)就是通常我們所說的堆棧。它用來保存函數的局部變量和參數。其操作方式類似于數據結構中的棧,是一種“后進先出”(Last In First Out,LIFO)的數據結構。這意味著最后放到棧上的數據,將會是第一個從棧上移走的數據,對于哪些暫時存儲的信息,和不需要長時間保存的信息來說,LIFO這種數據結構非常理想。在調用函數或過程后,系統通常會清除棧上保存的局部變量、函數調用信息及其它信息。棧的頂部通常在可讀寫的RAM區的最后,其地址空間通常“向下減少”,即當棧上保存的數據越多,棧的地址就越小。

        堆(heap)就是通常我們說的動態內存分配。它用來管理動態內存的。其操作方式跟數據結構中的堆,是不同的。

        在ARM的集成開發環境中,

        1、只讀的代碼段稱為Code段,即上述的.text段。

        2、只讀的常量數據段,被稱作RO Data段,即上述的.constdata段。

        以上兩個段統稱為RO段(Read Only),放在ROM或FLASH等非易失性器件中。

        3、可讀可寫的初始化了的全局變量和靜態變量段,被稱作RW Data段(ReadWrite),即上述的.bss段。

        4、可讀可寫的未初始化的全局變量和靜態變量段,被稱作ZI Data段(Zero Init),即上述的.data段。因為這個段里的變量要被初始化為零,所以叫ZI段。

        以上兩個段統稱為RW段,而在運行時,它必須重新裝載到可讀可寫的RAM中。




        關鍵詞: ARM編譯空間屬

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 大竹县| 三都| 司法| 九龙坡区| 苗栗县| 麻栗坡县| 开鲁县| 武鸣县| 和平区| 沈丘县| 广东省| 湛江市| 电白县| 仁怀市| 环江| 新源县| 鄄城县| 淮南市| 肇东市| 邮箱| 汕尾市| 三门峡市| 昌图县| 花莲市| 宁远县| 鱼台县| 太和县| 康乐县| 乐陵市| 海原县| 辽源市| 普宁市| 玛多县| 长岛县| 叶城县| 浦东新区| 佛冈县| 洱源县| 吐鲁番市| 康保县| 溧水县|