原创 IAR FOR AVR 编译环境中全局变量的空间分配和初始化的分析

2010-5-26 09:51 7265 6 6 分类: MCU/ 嵌入式

         IAR FOR AVR 编译环境中全局变量的空间分配和初始化的分析


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


1. 例子1


程序中仅包含一个空的main()函数,代码如下:


#include <ioavr.h>   


char s[100];


int main(void)


{


}


 


此时对应的map文件显示:


84a7bdf3-78de-4b2f-b75f-d610eea17b5e.JPG 


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


 

 


    表中除了前面见过的段外,增加了INITTABTINY_ITINY_ZTINZ_I的大小为0,暂时先不管它。TINY_Z的大小为100,正好是数组s的大小,因此可以看出全局变量的空间分配就从RAM空间的第1个字节(地址为0060H)开始,而数据堆栈和返回地址堆栈则放到后面去。


另外,还有一个段是INITTAB,这个比较有意思,通过IAR的模拟软件,从内存中可以看出,这6个字节的值(十六进制)为:640060000000。那么这6个参数的含义究竟是什么呢?


可以看成三个参数,即0064H0060H0000H,这样就比较明确了,0064H就是数组大小100,而0060H就是这个数组的起始地址,根据改段的名称为INITTAB,可以猜测,0000H就是这个数组上电后要初始化的数值。这样也就能够解释为什么C语言的程序上电后,定义的全局变量的值都是0的现象了。也就是说,如果在C语言中的全局变量的初始值是0,那么就没有必要在程序再初始化了。


 


2.例子2


下面的程序则除了声明一个全局的数组外,还对其进行了初始化。


#include <ioavr.h>   


char s[10]={"0123456789"};


int main(void)


{


    int i;


    for(i=0;i<10;i++)


    {


        s = 123;


    }


}


编译后,MAP文件中的各段的信息如下:


321d7899-bfb1-46d2-96ef-a507dfbffaa8.JPG


 


 



在这里我们看到数据段中没有了TINY_Z(这是要初始化成0的数据段),而TINY_I的大小为10,就是数组s的大小,从字面应该能猜出,这个段的数据是需要进行非0的初始化的。特别需要指出的是,在CODE空间中增加了一个TINY_ID段,大小也是10。通过地址观察内存中的内容恰好就是30H31H32H33H34H35H36H37H38H39H,这些值就是对应的字符数组“0123456789”。也就是说,这些数值事先固化在FLASH中,当程序启动后,再将移动到RAM中,在启动代码中应该包含有这样的代码,通过反汇编,我们可以看到这部分代码,如下图所示:


 


55f316b3-9501-43bf-94ee-9f5aa3591489.JPG



通过上面分析,基本上比较清楚了全局变量的空间分配和初始化的问题。


 


                          <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2010518星期

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /2 下一条