搜索
bottom↓
回复: 13

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

[复制链接]

出0入0汤圆

发表于 2010-10-7 16:56:50 | 显示全部楼层 |阅读模式
在IAR中,堆和栈是分开设置的,堆用于存放全局变量,而栈用于存放局部变量。在最近的项目的中我就遇到了堆和栈溢出的情况。以下问题都是在NEC的0537中出现的。
一.        堆的溢出
在项目中,我定义了很多全局变量,而且这些全局变量都很大。刚开始定义的全局变量都没有问题,但是后来我定义了一个数组unsigned char testaddb[20];链接的时候出现了以下错误:
Error[e16]: 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(参考图一),再编译链接,错误消失。


(原文件名:clip_image002.jpg)
图一
二.        栈的溢出
不久堆的问题解决了,但是栈的问题又出现了。我编写了一个子函数,函数里定义了一个局部数组tempbuff[188];当程序这个函数的时候就出现了如下错误:
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_init  unsigned char tempbuff[188];
#pragma dataseg=default

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

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

出0入0汤圆

发表于 2010-10-22 14:43:35 | 显示全部楼层
说得很详细,很好.

出0入0汤圆

发表于 2010-11-3 10:46:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-22 18:03:04 | 显示全部楼层
很好,mark

出0入0汤圆

发表于 2010-12-5 15:36:16 | 显示全部楼层
感谢分享,IAR虽好用,就是感觉设置很麻烦!

出50入0汤圆

发表于 2010-12-5 23:47:36 | 显示全部楼层
IAR的堆栈需要人工设置是致命的缺陷 另外是断点数量
这点KEIL就做得很不错

出0入0汤圆

发表于 2012-9-13 17:23:59 | 显示全部楼层
mark!留用

出0入0汤圆

发表于 2012-9-13 18:30:51 | 显示全部楼层
比较庆幸的是在编译的时候就能发现 要是在单片机中运行程序后再触发堆栈溢出 就比较难debug了

出0入0汤圆

发表于 2012-9-13 18:41:48 | 显示全部楼层
很不错,avr可以借鉴。不过没说如何设置使得既不浪费也不出错。

出0入0汤圆

发表于 2012-10-7 19:20:44 | 显示全部楼层
不错,值得研究

出0入0汤圆

发表于 2012-10-8 11:41:56 | 显示全部楼层
不错,有机会学习下IAR,虽然KEIL用的方便,但是很傻瓜,感觉学习不到编译器内部的知识!

出0入0汤圆

发表于 2013-8-22 23:48:28 | 显示全部楼层
好,支持一下!

出0入0汤圆

发表于 2013-8-23 16:15:57 | 显示全部楼层
堆栈溢出是编程过程中最容易忽视的问题,楼主这个帖子给我们这些程序猿敲响了警钟,解答的很详细,看来楼主对这个理解已经较深了!谢谢分享!

出0入0汤圆

发表于 2014-7-29 06:30:55 | 显示全部楼层
我用IAR FOR NEC 4.6编译9222时出现以上错误,现在还没有解决呢?堆栈大小怎么设置?能帮助一下吗?谢谢!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 15:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表