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文件显示:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
表中除了前面见过的段外,增加了INITTAB、TINY_I和TINY_Z。TINZ_I的大小为0,暂时先不管它。TINY_Z的大小为100,正好是数组s的大小,因此可以看出全局变量的空间分配就从RAM空间的第1个字节(地址为0060H)开始,而数据堆栈和返回地址堆栈则放到后面去。
另外,还有一个段是INITTAB,这个比较有意思,通过IAR的模拟软件,从内存中可以看出,这6个字节的值(十六进制)为:64,00,60,00,00,00。那么这6个参数的含义究竟是什么呢?
可以看成三个参数,即0064H,0060H,0000H,这样就比较明确了,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文件中的各段的信息如下:
在这里我们看到数据段中没有了TINY_Z(这是要初始化成0的数据段),而TINY_I的大小为10,就是数组s的大小,从字面应该能猜出,这个段的数据是需要进行非0的初始化的。特别需要指出的是,在CODE空间中增加了一个TINY_ID段,大小也是10。通过地址观察内存中的内容恰好就是30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,这些值就是对应的字符数组“0123456789”。也就是说,这些数值事先固化在FLASH中,当程序启动后,再将移动到RAM中,在启动代码中应该包含有这样的代码,通过反汇编,我们可以看到这部分代码,如下图所示:
通过上面分析,基本上比较清楚了全局变量的空间分配和初始化的问题。
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2010年5月18日星期二
文章评论(0条评论)
登录后参与讨论