ARM程序剖析--ARM程序结构,Image文件结构等

发布时间:2024-09-18  

说明:1、今天学习到ARM程序,于是到网上找了不少资料,发现真正有用的并不是很多。而且经过我的实际测试,与网上部分大神说的有不少出入。


2、测试环境 WinXp  RVDS2.2的编译器和连接器


3、关于测试使用的工具           


一、ARM程序的组成

此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的映像(image)文件。烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。


一个ARM程序包含3部分:RO,RW 和 ZI


RO:是程序中的指令和常量      ,ReadOnly    只读的代码段和常量

RW:是程序中的已初始化变量  , ReadWrite  可读写的全局变量和静态变量

ZI:是程序中的未初始化的变量 , ZeroInit      RW段中要被初始化为零的变量的段(也就是说该段包含在RW内)

由以上3点在C语言中的表现:


1、C 中的指令以及常量被编译后是RO类型数据。

2、C 中的未被初始化或初始化为0的变量编译后是ZI类型数据。(这点注意)

3、C 中的已被初始化成非0值的变量编译后是RW类型数据。


关于上面的这些,我将在下面,用实际的例子来说明。


二、ARM映像文件的组成

        所谓ARM映像文件其实就是可执行文件,也成为image文件,又叫ELF文件。包括bin或hex两种格式,可以直接烧到rom里执行。在AXD调试过程中,我们调试的是 .axf 文件,其实这也是一种映像文件,它只是在bin文件中加了一个文件头和一些调试信息。


        映像文件一般由域组成,域最多由三个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中RO段和RW段,还有所谓的ZI段,这就是输出段。


        加载域:就是Image被静态存放的区域,一般就是指烧在flash中的整个bin文件;


        运行域:通常是程序都是被搬到SDRAM中运行,该Image被搬在SDRAM里工作所处的地址空间就是运行域。


对于加载域中的输出段,一般来说RO段后面紧跟着RW段,RW段后面紧跟着ZI段。在运行域中这些输出段并不连续,但RW和ZI一定是连着的。ZI段和RW段中的数据其实可以是RW属性。


        Image文件一般只包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。


实际上,ROM中的指令至少应该有这样的功能:

        1、将RW从ROM中搬到RAM中。因为RW是变量,变量不能存在ROM中。

        2、将ZI所在的RAM区域全部清零。因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中

在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。


三、实例测试

(1) RO段测试


下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中一条语句的大小。


Pro1:


   1: #include

   2: void main(void)

   3: {

   4: ;

   5: }

Pro2:


   1: #include

   2: const char ch = 2;  // 常量

   3: void main(void)

   4: {

   5: ;

   6: }

Pro3:


   1: #include

   2: const char ch = 2;

   3: int main(void)

   4: {

   5:     return 0;

   6: }

Pro1的编译结果:


      Code   (inc. data)   RO Data    RW Data    ZI Data      Debug  


      932      32            16          0         96          0   Grand Totals

      932      32            16          0         96          0   Image Totals


================================================================================


    Total RO  Size (Code + RO Data)                          948 (   0.93kB)

    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)

    Total ROM Size (Code + RO Data + RW Data)        948 (   0.93kB)


================================================================================


Pro2的编译结果:


      Code  (inc. data)   RO Data    RW Data    ZI Data      Debug  


      932      32          20          0         96          0   Grand Totals

      932      32          20          0         96          0   Image Totals


================================================================================


    Total RO  Size (Code + RO Data)                          952 (   0.93kB)

    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)

    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)


================================================================================


Pro3的编译结果:


      Code    (inc. data)   RO Data    RW Data    ZI Data      Debug  


       936         32             20              0             96          0   Grand Totals

       936         32             20              0             96          0   Image Totals


================================================================================


    Total RO  Size (Code + RO Data)                          956 (   0.93kB)

    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)

    Total ROM Size (Code + RO Data + RW Data)        956 (   0.93kB)


================================================================================


由上面的编译结果(尤其是加红部分)可知:常量被放在了 RO段中,验证第一点。增加一条语句时,Code部分大小增大。


(2) RW段测试


Pro4和Pro1 之间只相差一个“已初始化为非零的变量“,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。


Pro4:


   1: #include

   2: char a = 5;

   3: void main(void)

   4: {

   5: ;

   6: }

Pro5:


   1: #include

   2: char a = 0;

   3: void main(void)

   4: {

   5: ;

   6: }

Pro4 的编译结果:


      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  


       932         32              16             4             96          0   Grand Totals

       932         32              16             4             96          0   Image Totals


================================================================================


    Total RO  Size (Code + RO Data)                          948 (   0.93kB)

    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)

    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)


================================================================================


Pro5 的编译结果:


      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  


       932         32             16              4             96          0   Grand Totals

       932         32             16              4             96          0   Image Totals


================================================================================


    Total RO  Size (Code + RO Data)                          948 (   0.93kB)

    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)

    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)


================================================================================


Pro4与 Pro1 相比,只有 RW Data段 多了4字节。


在Pro5中,对于初始化为0的变量,其仍然放在了RW区。


(3) ZI 段测试


Pro5 和 Pro1 之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。


Pro5:


   1: #include

   2: char a;

   3: void main(void)

   4: {

   5: ;

   6: }

Pro5的编译结果:


      Code      (inc. data)   RO Data    RW Data    ZI Data      Debug  


       932             32          16              4             96          0   Grand Totals

       932             32          16              4             96          0   Image Totals


================================================================================


    Total RO  Size (Code + RO Data)                          948 (   0.93kB)

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>