打印

一个很奇怪的代码

[复制链接]
2579|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sjc_sugar|  楼主 | 2012-7-31 17:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sjc_sugar 于 2012-8-1 18:40 编辑

一个学弟刚学习单片机,代码出现一点问题,帮他调试下,这一调试,变发现一个奇怪的现象,发表下,大家共同分析下:
#include<reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code sz1[]="AT+CMGF=1\x0d\x0a";
uchar code sz2[]="AT+CMGS=\"15716591375\"\x0d\x0a";
uchar code sz3[]="Hello,nihao\x1a";
void delay(uint z)     
{
uint x,y;
for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void fasong(uchar dat)
{
SBUF=dat;
while(!TI);
TI=0;
}
void main()
{
uchar i=0;
TMOD=0x20;
SCON=0x50;
TH1=0xfd;
TL1=0xfd;
EA=1;
ES=0;
TR1=1;
while(sz1!='\0')
{   
  fasong(sz1);
  i++;
  delay(5);   
}
delay(1000);
i=0;
while(sz2!='\0')
{   
  fasong(sz2);
  i++;
  delay(5);   
}
delay(1000);
i=0;
while(sz3!='\0')
{   
  fasong(sz3);
  i++;
  delay(5);   
}
delay(1000);  
while(1);
}
调试发现,进入蓝色部分,程序不规则跳转,先跳到delay(5)但是不执行;然后跳到fasong()函数,然后跳到while(1),最后执行delay(5)延时;完了后发送第二个字符;更怪异的是,将uchar该为int类型,程序跳转正常,但生成的code多了50byte,大家一起分析下哈,看看反汇编是怎么跑的!


这是添加截图:希望大家可以帮忙分析下,共同进步!


8级优化,只将uchar改为int后的结果。

1.jpg (37.41 KB )

1.jpg

2.jpg (38.97 KB )

2.jpg

相关帖子

沙发
林粼粼| | 2012-7-31 19:37 | 只看该作者
while(sz1[i]!='\0')
{   
  fasong(sz1);
  i++;
  delay(5);   
}

下面的同上

使用特权

评论回复
板凳
林粼粼| | 2012-7-31 19:38 | 只看该作者
fasong(sz1[i]);
漏了

使用特权

评论回复
地板
原野之狼| | 2012-7-31 19:41 | 只看该作者
看2L的 还有就是开了优化

使用特权

评论回复
5
sjc_sugar|  楼主 | 2012-8-1 18:28 | 只看该作者
3# 林粼粼
不好意思,贴错了,原程序就是fasong(sz);可能是4L的,用的是默认8level优化!

使用特权

评论回复
6
sjc_sugar|  楼主 | 2012-8-1 18:33 | 只看该作者
4# 原野之狼
确实,将优化8level改为7,正常的跳转!在8level下,为什么将uchar改为int就正常了?而且代码code长度却增加50bytes,不理解!

使用特权

评论回复
7
qiujiahongde| | 2012-8-1 21:05 | 只看该作者
优化!

使用特权

评论回复
8
ningling_21| | 2012-8-1 21:42 | 只看该作者
都是优化惹的祸...

使用特权

评论回复
9
sjc_sugar|  楼主 | 2012-8-2 08:37 | 只看该作者
8# ningling_21
一般情况下,我都是用的是默认8level优化,如果出现这情况,解决办法:降低优化等级(会增加代码code长度),不知道大侠您是怎么处理的!

使用特权

评论回复
10
sjc_sugar|  楼主 | 2012-8-2 08:38 | 只看该作者
7# qiujiahongde
我用的是8level优化,难道降低优化等级或者增高优化等级解决同类问题么?

使用特权

评论回复
11
yiucing| | 2012-8-2 10:08 | 只看该作者
看了一下汇编代码
只是代码被复用了
全速运行应该没问题吧

使用特权

评论回复
12
xwj| | 2012-8-2 10:10 | 只看该作者
正常。

高级别优化时很多语句生成的部分代码是相同的,也有的语句的代码是非显示或者被换了地方的,所以和C语言源码会有很多地方对不上。

但是,你仔细观察它的行为和结果的话,就会发现:它优化后的代码执行完的行为和你的C语言需要的行为是完全一致的!

比如装入变量后再调用函数(有参函数),比如函数的退出(ret),由于A函数和B函数前后这两个部分是完全一样的,所以编译器优化后就共用了,结果调试时你就很可能看到调用A函数,单步却会跳到B函数的开头,然后又真的进了A函数,完了却后回到B的结尾括号,然后又正确的返回了函数的调用点...

这还只是简单的,更复杂的优化甚至能看的你神经错乱哦~:)
所以,高级别优化行为和结果通常都是对的,但是可读性和可跟踪性是完全乱七八糟的,调试时应该先降低优化级别再调!

有空时多看看编译器的说明,就知道每个级别优化了什么内容,也就知道实际该选几级优化了。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
sjc_sugar + 1
13
cjseng| | 2012-8-3 09:51 | 只看该作者
xwj所说的,在switch case 语句中经常可以观察到,跳转根本不按照自己期望的那样来,一开始觉得奇怪,后来跟踪调试了一下,发现结果完全正常。再仔细一分析,基本上就是共用了共同的代码,想想编译器还真是抠门,连这点代码都要省。

使用特权

评论回复
14
aihe| | 2012-8-4 11:22 | 只看该作者
要不省,你别开优化啊

使用特权

评论回复
15
xwj| | 2012-8-5 08:46 | 只看该作者
...
想想编译器还真是抠门,连这点代码都要省。cjseng 发表于 2012-8-3 09:51


呵呵,比开了优化就是要求编译器帮你省啊,编译器当然就得按你的要求省了;
要不省,你别开优化啊:)

使用特权

评论回复
16
大道至简| | 2012-8-8 08:48 | 只看该作者
没有看你的程序,从截图看,被变量类型变化后,code空间变小正常啊
之所以变小这么多,是因为你多次使用i

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

70

帖子

1

粉丝