gha20028 发表于 2010-10-7 16:56:50

IAR 堆栈溢出小结,请大家拍砖

在IAR中,堆和栈是分开设置的,堆用于存放全局变量,而栈用于存放局部变量。在最近的项目的中我就遇到了堆和栈溢出的情况。以下问题都是在NEC的0537中出现的。
一.        堆的溢出
在项目中,我定义了很多全局变量,而且这些全局变量都很大。刚开始定义的全局变量都没有问题,但是后来我定义了一个数组unsigned char testaddb;链接的时候出现了以下错误:
Error: Segment CSTACK (size: 0x80 align: 0x1) is too long for segment definition. At least 0x14 more bytes needed. The problem occurred while processing the segment   
placement command "-Z(DATA)CSTACK+_CSTACK_SIZE=FB00-FE1F", where at the moment of placement the available memory ranges were "CODE:fda3-fe1f"
   Reserved ranges relevant to this placement:
   fb00-fda2            NEAR_Z
   fda3-fe1f            CSTACK
   700-75f            SADDR_A
   780-79f            SADDR_A
   800-84f            NEAR_A
   860-867            NEAR_A
   870-88f            NEAR_A
   898-8af            NEAR_A
   8b8-8bf            NEAR_A
   8f0-8f7            NEAR_A
   900-907            NEAR_A
   940-94f            NEAR_A
   978-987            NEAR_A
   9b0-9c7            NEAR_A
   a78-a7f            NEAR_A
   bc8-bcf            NEAR_A
   bf8-c17            NEAR_A
   c80-c9f            NEAR_A
   cb0-cff            NEAR_A
   e00-e3f            NEAR_A
   e80-e87            NEAR_A
   ea0-ea7            NEAR_A
   ed8-edf            NEAR_A
Error while running Linker

上面的错误意思是CSTACK (栈)设置得太大了,倒置变量没有地方放,需要0x14个字节,然后我在设置中将Stack的大小从0x80改成了0x6C(参考图一),再编译链接,错误消失。

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_588083SJBHVN.jpg
(原文件名:clip_image002.jpg)
图一
二.        栈的溢出
不久堆的问题解决了,但是栈的问题又出现了。我编写了一个子函数,函数里定义了一个局部数组tempbuff;当程序这个函数的时候就出现了如下错误:
Thu Oct 07 16:20:36 2010: The stack 'Stack' is filled to 100% (128 bytes used out of 128). The warning threshold is set to 90.%
错误的意思就是'Stack'溢出了。
分析发现,我子函数中的局部变量需要188字节的空间,而实际栈中只有128字节,当然后爆错了。将数组改小或者将数组定义成全局变量就能解决问题。
三.        扩展RAM的使用
NEC0537有6144字节的扩展RAM,该区域空间除了不能作为堆栈存储器使用,其他功能和RAM区一样,所以我们可以把全局变量放到扩展RAM中,定义方法如下:
#pragma dataseg=IXRAM          //--------------------将全局变量放在扩展RAM区间
__no_initunsigned char tempbuff;
#pragma dataseg=default

注1,        定义变量时__no_init不能去掉。
注2,        前面说道的堆栈存储器是0537中文资料上提到的,由于前面已将堆和栈分开提及,所以此处的堆栈存储器我认为是栈存储器。

以上为本人的个人观点,如有什么错误请大家拍砖。

lo-lo25 发表于 2010-10-22 14:43:35

说得很详细,很好.

sytu_xww 发表于 2010-11-3 10:46:18

mark

ksh84222 发表于 2010-11-22 18:03:04

很好,mark

radarOV123 发表于 2010-12-5 15:36:16

感谢分享,IAR虽好用,就是感觉设置很麻烦!

god-father 发表于 2010-12-5 23:47:36

IAR的堆栈需要人工设置是致命的缺陷 另外是断点数量
这点KEIL就做得很不错

dreamboy 发表于 2012-9-13 17:23:59

mark!留用

NemoGu 发表于 2012-9-13 18:30:51

比较庆幸的是在编译的时候就能发现 要是在单片机中运行程序后再触发堆栈溢出 就比较难debug了

heize 发表于 2012-9-13 18:41:48

很不错,avr可以借鉴。不过没说如何设置使得既不浪费也不出错。

mcu-avr 发表于 2012-10-7 19:20:44

不错,值得研究

sugar7171519 发表于 2012-10-8 11:41:56

不错,有机会学习下IAR,虽然KEIL用的方便,但是很傻瓜,感觉学习不到编译器内部的知识!

Maurice 发表于 2013-8-22 23:48:28

好,支持一下!

g22261846 发表于 2013-8-23 16:15:57

堆栈溢出是编程过程中最容易忽视的问题,楼主这个帖子给我们这些程序猿敲响了警钟,解答的很详细,看来楼主对这个理解已经较深了!谢谢分享!

牛东 发表于 2014-7-29 06:30:55

我用IAR FOR NEC 4.6编译9222时出现以上错误,现在还没有解决呢?堆栈大小怎么设置?能帮助一下吗?谢谢!!
页: [1]
查看完整版本: IAR 堆栈溢出小结,请大家拍砖