历史上的今天

今天是:2024年09月20日(星期五)

正在发生

2018年09月20日 | ARM中的RO段、RW段和ZI段的区别

发布者:幸福旅程 来源: eefocus关键字:ARM  RO段  RW段  ZI段 手机看文章 扫描二维码
随时随地手机看文章

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程序才能正常访问变量。否则只能运行不含变量的代码。


5 实例


说了上面的可能还是有些迷糊,RO,RW和ZI到底是什么,下面我将给出几个例子,最直观的来说明RO,RW,ZI在C中是什么意思。


5.1 RO


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


Prog1:


[cpp] view plaincopy

#include  

void main(void)  

{  

      ;  

}  

Prog2:


[cpp] view plaincopy

#include  

const char a = 5;  

void main(void)  

{  

    ;  

}  

Prog1编译出来后的信息如下:


[plain] view plaincopy

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

Code RO Data RW Data ZI Data Debug  

948  60      0       96      0    Grand Totals  

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

Total RO Size(Code + RO Data) 1008 ( 0.98kB)  

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

Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)  

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

Prog2编译出来后的信息如下:


[plain] view plaincopy

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

Code RO Data RW Data ZI Data Debug  

948  61      0       96      0    Grand Totals  

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

Total RO Size(Code + RO Data) 1009 ( 0.99kB)  

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

Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)  

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

以上两个程序编译出来后的信息可以看出:

            Prog1和Prog2的RO包含了Code和RO Data两类数据。他们的唯一区别就是Prog2的RO Data比Prog1多了1个字节。这正和之前的推测一致。

            如果增加的是一条指令而不是一个常量,则结果应该是Code数据大小有差别。


5.2 RW


同样再看两个程序,他们之间只相差一个“已初始化的变量”,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。

Prog3:


[cpp] view plaincopy

#include  

void main(void)  

{  

         ;  

}  

Prog4:


[cpp] view plaincopy

#include  

char a = 5;  

void main(void)  

{  

          ;  

}  


Prog3编译出来后的信息如下:


[plain] view plaincopy

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

Code RO Data RW Data ZI Data Debug948  60      0       96      0    Grand Totals  

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

Total RO Size(Code + RO Data) 1008 ( 0.98kB)  

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

Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)  

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

Prog4编译出来后的信息如下:


[plain] view plaincopy

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

Code RO Data RW Data ZI Data Debug  

948  60      1       96      0    Grand Totals  

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

Total RO Size(Code + RO Data) 1008 ( 0.98kB)  

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

Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)  

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

可以看出Prog3和Prog4之间确实只有RW Data之间相差了1个字节,这个字节正是被初始化过的一个字符型变量“a”所引起的。


5.3 ZI


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

Prog5:


[cpp] view plaincopy

#include  

void main(void)  

{  

           ;  

}  


Prog6:


[cpp] view plaincopy

#include  

char a;  

void main(void)  

{  

             ;  

}  


Prog5编译出来后的信息如下:


[plain] view plaincopy

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

Code RO Data RW Data ZI Data Debug  

948  60      0       96      0    Grand Totals  

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

Total RO Size(Code + RO Data) 1008 ( 0.98kB)  

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

Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)  

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

Prog6编译出来后的信息如下:


[plain] view plaincopy

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

Code RO Data RW Data ZI Data Debug  

948 60 0 97 0 Grand Totals  

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

Total RO Size(Code + RO Data) 1008 ( 0.98kB)  

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

Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)  

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

编译的结果完全符合推测,只有ZI数据相差了1个字节。这个字节正是未初始化的一个字符型变量“a”所引起的。

注意:如果一个变量被初始化为0,则该变量的处理方法与未初始化华变量一样放在ZI区域。

即:ARM C程序中,所有的未初始化变量都会被自动初始化为0。


6 总结


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

2; C中的未被初始化或初始化为0的变量编译后是ZI类型数据。

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


关键字:ARM  RO段  RW段  ZI段 引用地址:ARM中的RO段、RW段和ZI段的区别

上一篇:STM32 PWM 占空比可变函数
下一篇:基于stm32的usb iap程序升级步骤

推荐阅读

  “531新政”出台后,国内很多光伏逆变器企业都将视线投向海外,一场“异地”较量正在上演。   近年来,中国光伏产业高速发展,无论是制造端还是技术端都处于全球领先地位。但从某种意义上说,如此高速发展是在国内需求旺盛的基础上得来的。目前中国光伏产业在经过连年的高速发展之后已经有些后继乏力,特别是国内市场已经难以保持巨大的需求。而随...
在iOS 14正式版本中,苹果引入的最大一个改变就是允许第三方应用替代Safari和Apple Mail成为系统默认的浏览器和电子邮件处理应用。伴随着第三方软件的更新,目前Safari的替代者包括Chrome、Edge、Firefox 和 DuckDuckGo。不过实际情况是,每当用户进行上述第三方应用更改时,设备重新启动后,就会出现一个诡异的Bug,即会将这些设置还原为苹果的默认应...
近日,根据上交所网站相关信息,深圳市中科蓝讯股份有限公司(以下简称“中科蓝讯”)公布了科创板IPO的首轮问询答复,其主要从事无线音频SoC芯片生产,可以应用于TWS蓝牙耳机等设备中。我们知道,当芯片与外部设备交互数据时,通常需要接口电路,并且可能还需要设置有多个接口电路,典型的接口电路由缓冲级和驱动级组成,如下图所示:其中,缓冲级负责接...

史海拾趣

问答坊 | AI 解惑

给想学linux的朋友一些建议

给想学linux的朋友一些建议(我学linux的体会) 一. 什么人会学linux? 这个问题涉及到linux是否会代替Windows。我认为绝对不可能。Windows易上手易学习的特点,以及Microsoft多年的积累,加上丰富的软件选择,是linux不可比拟的。 那为什么我们 ...…

查看全部问答∨

请教4数码管显示问题

大家好,我用的是holtek的HT46R322单片机,现在做一个程序,按加减键实现数字从0~9999变化,数码管用的是共阳的8位数码管,用循环点亮的方法。         我用一个存储单元保存要显示的数值,比如我要显示123,然后可 ...…

查看全部问答∨

十八般兵器-----------单片机励志篇

十八般兵器 快使用单片机,哼哼哈兮! 孔子说:“工欲善其事,必先利其器”,学习单片机所用的工具、元器件和数模电路是有一些区别的,我们在学习之前 最好先备齐它们,至少让外人看出我们是搞过单片机的。有几样东东很重要,在上场之前不得不提 ...…

查看全部问答∨

传AMD将推出3.3GHz双核速龙II处理器

本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 AMD不久前终于在移动计算机领域向英特尔发起了攻击,推出了一些新的移动处理器。但是,AMD还更新了其台式电脑芯片产品线。然而,总是有推出更多的处理器的空间,因为英特尔定期发布新的芯片。A ...…

查看全部问答∨

Wince6.0是否支持WPF

我用C#2008中的WPF做了个三维动画,怎么移植到Wince下,那位大虾能否赐教,不胜感谢.…

查看全部问答∨

c++如何取GPS数据

在C++上试取GPS数据,结果发现找不到GPSAPI.DLL,不知道谁有,还有,有人说可以通过直接读串口的方式实现,不知道谁会,给教教呀。               谢谢。…

查看全部问答∨

适合电桥小信号输出放大的差分放大器?

RT,在网上找了些,发现有个专门做电桥信号放大的芯片,AM457,AM467和AM417,可一问价格,二十几块钱,晕死, 这么贵! 不知道大家知不知道性价比好点的?…

查看全部问答∨

Pocket PC2003操作系统中,界面右上角的叉是什么函数控制的啊?

我要在作的程序实现这样的功能:当要退出程序时,点击右上角的叉叉,弹出一个提示对话框,选择是否要退出.但EVC右上角的叉不像VC一样是CMainFrame中的WM_CLOSE事件响应的,哪位高人前辈给我讲讲我该怎么做才能达到这样的效果呢??…

查看全部问答∨

232问题, 往PC机上发送数据,如何接收 ?

发送多于16个自己的数据, pc就接收困难。我PC部分使用com控件接收。在C#下编的程序。 不知道遇到类似问题的人,如何解决 这个问题的 。 我用的2812 。 …

查看全部问答∨

lmp90100芯片,有谁用过吗

本帖最后由 dontium 于 2015-1-23 12:48 编辑 有谁用过NS公司的lmp90100芯片没有,这两天我用这款芯片作为PT100和热电偶的前端处理,但是一直不能让芯片动起来,希望用过的朋友能提供一下调试经验,因为我用的是自己做的板子做的测试,现在无法定 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved