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类型数据。
上一篇:STM32 PWM 占空比可变函数
下一篇:基于stm32的usb iap程序升级步骤
推荐阅读
史海拾趣
宏发公司的发展离不开自主研发和技术创新。1998年,宏发成立了精合公司,开启了自主研发自动化设备设计及制造的征程。此后,公司不断加大在技术研发上的投入,建立了博士后科研工作站和院士专家工作站,形成了从产品研发、模具制造、零件制造到自动化成品装配及在线检测的一体化全产业链。通过技术创新,宏发不仅提升了产品性能和质量,还成功打破了国外技术垄断,实现了高端继电器的自主研发和生产。
随着环保意识的日益增强,Chipcon AS公司积极响应国家号召,将环保理念融入产品研发和生产过程中。公司采用环保材料和生产工艺,致力于降低产品对环境的影响。同时,公司还推出了一系列具有节能环保功能的电子产品,为客户提供了更加环保的选择。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实基础。
以上是根据电子行业的一般情况和趋势虚构的Chipcon AS公司的发展故事。这些故事旨在展示一个电子企业在不同方面可能经历的挑战和机遇,以及如何通过创新和合作实现持续发展。请注意,这些故事并非Chipcon AS公司的真实历史,仅供参考和启发。
DFRobot公司于2008年由叶琛创立,当时主要致力于将国外的开源硬件项目引入中国。起初,公司规模较小,团队由几位热爱机器人和开源硬件的工程师组成。他们凭借对技术的热情和不懈的努力,逐渐在电子行业崭露头角。叶琛作为公司的创始人,不仅拥有深厚的工程学背景,还具备前瞻性的商业眼光,为公司的发展奠定了坚实的基础。
随着全球环保意识的不断提高,Astec也开始关注绿色环保和可持续发展问题。公司积极采用环保材料和节能技术,推出了一系列绿色电源产品。同时,Astec还加大了对环保技术的研发力度,努力在保持产品性能的同时,降低生产过程中的能耗和排放。这些举措不仅有助于公司应对环保法规的挑战,还提升了公司的社会形象。
ACP Optoelectronic Technology Co Ltd始终坚持创新驱动的发展理念。公司不断投入研发资金,引进先进设备和技术人才,推动产品升级换代。随着市场的不断变化和客户需求的不断提升,ACP Optoelectronic Technology Co Ltd的产品线不断丰富和完善,产品质量和性能也得到了显著提升。
ACP Optoelectronic Technology Co Ltd始终坚持创新驱动的发展理念。公司不断投入研发资金,引进先进设备和技术人才,推动产品升级换代。随着市场的不断变化和客户需求的不断提升,ACP Optoelectronic Technology Co Ltd的产品线不断丰富和完善,产品质量和性能也得到了显著提升。
给想学linux的朋友一些建议(我学linux的体会) 一. 什么人会学linux? 这个问题涉及到linux是否会代替Windows。我认为绝对不可能。Windows易上手易学习的特点,以及Microsoft多年的积累,加上丰富的软件选择,是linux不可比拟的。 那为什么我们 ...… 查看全部问答∨ |
大家好,我用的是holtek的HT46R322单片机,现在做一个程序,按加减键实现数字从0~9999变化,数码管用的是共阳的8位数码管,用循环点亮的方法。 我用一个存储单元保存要显示的数值,比如我要显示123,然后可 ...… 查看全部问答∨ |
十八般兵器 快使用单片机,哼哼哈兮! 孔子说:“工欲善其事,必先利其器”,学习单片机所用的工具、元器件和数模电路是有一些区别的,我们在学习之前 最好先备齐它们,至少让外人看出我们是搞过单片机的。有几样东东很重要,在上场之前不得不提 ...… 查看全部问答∨ |
本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 AMD不久前终于在移动计算机领域向英特尔发起了攻击,推出了一些新的移动处理器。但是,AMD还更新了其台式电脑芯片产品线。然而,总是有推出更多的处理器的空间,因为英特尔定期发布新的芯片。A ...… 查看全部问答∨ |
RT,在网上找了些,发现有个专门做电桥信号放大的芯片,AM457,AM467和AM417,可一问价格,二十几块钱,晕死, 这么贵! 不知道大家知不知道性价比好点的?… 查看全部问答∨ |
Pocket PC2003操作系统中,界面右上角的叉是什么函数控制的啊? 我要在作的程序实现这样的功能:当要退出程序时,点击右上角的叉叉,弹出一个提示对话框,选择是否要退出.但EVC右上角的叉不像VC一样是CMainFrame中的WM_CLOSE事件响应的,哪位高人前辈给我讲讲我该怎么做才能达到这样的效果呢??… 查看全部问答∨ |
发送多于16个自己的数据, pc就接收困难。我PC部分使用com控件接收。在C#下编的程序。 不知道遇到类似问题的人,如何解决 这个问题的 。 我用的2812 。 … 查看全部问答∨ |
本帖最后由 dontium 于 2015-1-23 12:48 编辑 有谁用过NS公司的lmp90100芯片没有,这两天我用这款芯片作为PT100和热电偶的前端处理,但是一直不能让芯片动起来,希望用过的朋友能提供一下调试经验,因为我用的是自己做的板子做的测试,现在无法定 ...… 查看全部问答∨ |