疯狂,探寻出路.... https://bbs.21ic.com/?546345 [收藏] [复制] [RSS] 别想着一夜成材,也别怀疑自己是天才,成功需要时间的积累.失败了无所谓,别迷失方向才重要.懂得吸收比懂得模仿更实在,超越别人不如超越昨天的自己.不要跟着别人手指看月亮,只要你动手去做了,一定会有成果的...

日志

Keil中变量的存储分配

已有 650 次阅读2009-9-30 08:45 |个人分类:C/C++编程|系统分类:单片机

最近在裁减一个芯片的Demo程序,好多东西都用不上,于是疯狂地删除,其中有个操作让我百思不得其解:有时在主程序中注释掉对一个函数的调用,(函数定义仍保留),就会出现编译通不过,错误原因是存储空间溢出。
仔细看了一下,真正的原因是DATA溢出了,每次注释掉一个函数的调用之后,占用的内存DATA值就增加不少。
查看.m51文件,发现注释掉的函数里的局部变量会出现在DATA空间里,难道Keil如果发现某个函数未被调用,则把其中的局部变量当作是全局变量来处理,在编译链接时就分配内存,而不再与其他函数共享内存空间?

在ouravr论坛找到了比较详细的回答,原文如下:
51的资源比较少,所以在keil针对51的编译器分配内存的时候不是按照一种传统的方法来处理的。
如果是arm之类的,编译之后会产生RW,RO,ZO几个段,分别存储定义了的全局变量,代码常量以及没有定义的全局变量。所有局部变量都是放到堆栈中,调用函数的时候推进去,函数返回的时候弹出来。所以会出现你说的从一个函数返回以后内存空间释放一部分的情况(但是你好像只能看到RW,RO,看不到堆栈的最深长度,所以你一样无法通过定义一个局部变量来看到编译器输出结果有什么不同) 51分配内存的方法是把所有变量分到一个固定的地址,然后通过所谓的overlapped分析,发现那些函数是不可能同时调用的,就把一些不可能同时调用的函数变量分到一些相同的地址。你定义了一个局部变量数组,也许overlapped发现没法和别的函数变量共用地址,所以就会多占了一个数组的内存空间。
你可以尝试着在编译的时候把overlapped 优化关掉,就会发现更多的内存空间占用。这就是51编译器不同的地方,正是由于以上的原因,c51在实现一些C语言规定的语法的时候有一些局限性,比如指向函数的指针的使用就有一些限制,可以参考C51的参考文档看一下。
以上纯属个人观点。 aaa1982
http://www.ourdev.cn/bbs/bbs_content.jsp?xcfrom=302&bbs_sn=3486436

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)