SEGMENT: _DATA_GROUP_
LENGTH: 001BH
Program Size: data=124.3 xdata=0 code=5323
Target not created
===========================================
今天C51出现这样的错误,请问这是什么原因? DATA才124.3啊,另外请问下,KEIL C51里的局部变量用过后会不会立即释放?
比如下面这样
void accout()
{
unsigned char ch[5];
}
main()
{
unsigned char i;
...
{
unsigned j;
}
...
{
unsigned k;
}
...
accout();
}
j和k在它们所在的括号里面的语句执行玩后会不会释放空间?
我想了下,我只是在我的accout函数里增加了5个局部变量 ,结果就出现这样的错误
问题补充说明下,我的程序里临时用的变量我都习惯把它放到 大括号里,以为这样有利于编译器优化代码
不会主动释放,可能只有再次用到那块地址的时候,才会覆盖掉。
详细参考下面:
在C51中变量的空间分配几个方法
1、 data区空间小,所以只有频繁用到或对运算速度要求很高的变量才放到data区内,比如for循环中的计数值。
2、 data区内最好放局部变量。
因为局部变量的空间是可以覆盖的(某个函数的局部变量空间在退出该函数是就释放,由别的函数的局部变量覆盖),可以提高内存利用率。当然静态局部变量除外,其内存使用方式与全局变量相同;
3、 确保你的程序中没有未调用的函数。
在Keil C里遇到未调用函数,编译器就将其认为可能是中断函数。函数里用的局部变量的空间是不释放,也就是同全局变量一样处理。这一点Keil C做得很愚蠢,但也没办法。
4、 程序中遇到的逻辑标志变量可以定义到bdata中,可以大大降低内存占用空间。
在51系列芯片中有16个字节位寻址区bdata,其中可以定义8*16=128个逻辑变量。定义方法是: bdata bit LedState;但位类型不能用在数组和结构体中。
5、 其他不频繁用到和对运算速度要求不高的变量都放到xdata区。
6、 如果想节省data空间就必须用large模式,将未定义内存位置的变量全放到xdata区。当然最好对所有变量都要指定内存类型。
7、 当使用到指针时,要指定指针指向的内存类型。
在C51中未定义指向内存类型的通用指针占用3个字节;而指定指向data区的指针只占1个字节;指定指向xdata区的指针占2个字节。如指针 p是指向data区,则应定义为: char data *p;。还可指定指针本身的存放内存类型,如:char data * xdata p;。其含义是指针p指向data区变量,而其本身存放在xdata区。
非常感谢 4楼的回答,但还有点不明白就是我给出的代码示例里 main() 函数里面的大括号内的的变量生存期的问题,这是怎么处理的? 如果是在别的函数里又是怎么处理的? 也就是说j,k变量是要等到整个函数结束了才被释放还是只要大括号里的语句执行玩了就释放?
那里面的函数如果没有被调用,里面的变量就不会释放。被调用以后,才释放。
在KEIL C51上,局部变量并不像PC平台,放在栈里面,因为51的资源消费不起很贵的栈开消。
局部变量也是放在DATA区里,当然栈也在这里面
通常局部变量也会像PC平台的全局变量一样进入RAM区,不会被释放
只是通过C语言的语法控制其访问权限
感谢大家的帮助1!
我已经弄明白这个问题了,KEIL C51 跟我想像的一样,大括号里面的变量生存期只限在大括号内,通过KEIL C51 生成的汇编语句弄明白的
l例如下面这段代码,实际上 j 与 k 是一个内存地址。 也就是&j等于&k
MAIN函数里面的两个大括号内的语句生成的汇编语句也是完全一样的
main()
{
unsigned char i;
...
{
unsigned j;
j=0;
j++;
}
...
{
unsigned k;
k=0;
k++;
}
...
}