[STM8] 哭死哦,遇到如此变态的iar for stm8的bug

[复制链接]
7861|15
 楼主| donkey89 发表于 2011-8-11 10:51 | 显示全部楼层 |阅读模式
本帖最后由 donkey89 于 2011-8-11 11:53 编辑

过程很简单,功能就是把十六进制数缩小1万倍,变成十进制的字符串,例如数值15030,转换过来就是"15.030".但是居然能影响到另外一个毫不相干的函数的运行结果,我在过程的各个地方都加了限定条件,不会出现越界访问的情况
重点看
第48行
str[j++]=(char)(val/m)+'0';
把这个注释掉或者把J++变成立即数都不会再出现问题了.例如
str[5]=(char)(val/m)+'0';

  1. 代码没法跟踪,到那一段自动非法错误退出
  2. //******************
  3. //功能:调用hex2str并显示到lcd上
  4. //*******************
  5. void lcd_printf_int(uint16_t n)
  6. {
  7.   char str[9];//这个数组足够大了,实际仅仅用到7个字节而已
  8. //  char i;
  9. //  i=sprintf(str,"%d",n);
  10. //  if(i>8) str[8]='\0';
  11.   hex2str(n,str);
  12.   lcd_puts(str);
  13. }

  14. //***********************
  15. //功能:数值转换成字符串的函数
  16. //参数n:要转换的数
  17. //参数str:转换结果存储的地方
  18. //************************
  19. void hex2str(uint16_t n,char *str)
  20. {
  21.   uint16_t val,m;
  22.   char i,j;
  23.   
  24.   m=10000;
  25.   val=n;
  26.   j=0;
  27.   for(i=0;i<2;i++)
  28.   {
  29.     if(val>=m)
  30.     {
  31.       str[j++]=(char)(val/m)+'0';
  32.       val%=m;
  33.     }
  34.     else if(val<n)
  35.       str[j++]='0';
  36.     m/=10;
  37.   }
  38.   if(j==0)
  39.       str[j++]='0';
  40.   str[j++]='.';
  41. //*************以上处理的是大于1的部分**************
  42.   
  43.   for(;i<5;i++)
  44.   {
  45.     if(val>=m)
  46.     {
  47.       if(j<6)
  48.         str[j++]=(char)(val/m)+'0';//这里,如果把J++换成<5的立即数,就不会影响另外一个完全不相关的函数
  49.       val%=m;
  50.     }
  51.     else if(j<6)
  52.       str[j++]='0';   
  53.     m/=10;
  54.   }
  55. //*************小数点部分*************
  56.   
  57.   str[6]='\0';
  58. }
wangjckj 发表于 2011-8-11 11:06 | 显示全部楼层
这样类似的问题在IAR STM8 中经常见到,估计还是不成熟。我都见惯不怪了
上官金虹 发表于 2011-8-11 11:20 | 显示全部楼层
堆栈是否足够?
你的影响到额外不相关函数是什么函数?
 楼主| donkey89 发表于 2011-8-11 11:32 | 显示全部楼层
本帖最后由 donkey89 于 2011-8-11 11:46 编辑

2楼,你遇到这种情况怎么绕开?

3# 上官金虹
heap的大小为256字节,堆栈为256字节,怎么会不够?
我重新设置了更大的heap和stack,依然不行
wangjckj 发表于 2011-8-11 11:36 | 显示全部楼层
3#
堆栈绝对没问题!

4#
解决办法就是调整代码重新编译。
香水城 发表于 2011-8-11 12:37 | 显示全部楼层
会不会有代码重入的问题?
yinyangdianzi 发表于 2011-8-11 13:06 | 显示全部楼层
 楼主| donkey89 发表于 2011-8-11 13:22 | 显示全部楼层
6# 香水城
妹哦,代码就在一楼,你看看有没有可以重入的地方?希望你能找出来,这样帮了我一个大忙了.还可以让大家引以为戒
上官金虹 发表于 2011-8-11 18:44 | 显示全部楼层
你的影响到额外不相关函数是什么函数?
 楼主| donkey89 发表于 2011-8-11 20:30 | 显示全部楼层
本帖最后由 donkey89 于 2011-8-11 20:34 编辑

9# 上官金虹
运算函数,根据AD值,然后经过特殊算法得到一个值
字符串转换函数我跟踪进去就崩溃.看反汇编没有ret,不知道跳到哪去了.屏蔽掉代码重新编译可以看到ret指令.
整个转换函数我在其他编译器上测试通过了,才拷贝过来用的.
ccmc 发表于 2011-8-11 22:28 | 显示全部楼层
算术越界了........?
linqing171 发表于 2011-8-12 07:13 | 显示全部楼层
经过详细核对,发现
1: 运算过程稍微复杂。
2: 运算输出结果完全正确,包括各种数据输入情况下。
3: 无除以0等操作的可能。
4: 数组无溢出可能。堆栈使用固定,不可能到最后面的时候采出错。

烦请楼主贴list文件,看汇编怎么回事。
香水城 发表于 2011-8-12 09:39 | 显示全部楼层
6# 香水城
妹哦,代码就在一楼,你看看有没有可以重入的地方?希望你能找出来,这样帮了我一个大忙了.还可以让大家引以为戒
donkey89 发表于 2011-8-11 13:22


比如讲,这个运算就不是可重入的:(val/m)
yewuyi 发表于 2011-8-12 09:43 | 显示全部楼层
搞不懂LZ这么写有什么优点。

1、首先LZ弄错了,‘例如数值15030,转换过来就是"15.030".’,这是缩小1000倍。
2、看LZ好像是送LCD显示,如果是俺,宁可这样写:
d1=val/10000;
d2=(val%10000)/1000;
d3=(val%1000)/100;
d4=(val%100)/10;
d5=val%10;
多简单明了,如果想转换成字符串,上面的d1~d5转换一下非常容易。
 楼主| donkey89 发表于 2011-8-16 08:55 | 显示全部楼层
14# yewuyi
您的代码很直观,我这么写是为了省空间而已,空间不够用了.我试试你的写法看看能不能省空间.
其实我对C嵌入汇编不熟,否则直接用汇编了.
t.jm 发表于 2011-8-16 09:13 | 显示全部楼层
if(j<6)

        str[j++]=(char)(val/m)+'0';//这里,如果把J++换成<5的立即数,就不会影响另外一个完全不相关的函数
....
m/=10;

肯定是0除了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:数显ESR电容等效内阻测量仪 http://cn.digit-esr.com

241

主题

1609

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部