标题: 一个keil编译bug--已经解决 [打印本页]

作者: 片机小白    时间: 2020-5-8 16:37
标题: 一个keil编译bug--已经解决
中断改变变量的值无法正常赋值给循环体.例:int i =1;
main()
{
   while (i);
}
void USART1_IRQHandler(void){
        i=0;
}

这样无法跳出循环..  如图 右下 内存a 已经为1 却无法跳出 while(!a);这个循环
大概是因为汇编代码 只赋值了一次值给R0  请问有什么办法解决嘛?

作者: carpcarey    时间: 2020-5-8 17:00
是你的问题
当a=1
则!a是对1取反
while(!a);是对a取反,直到a取反后等于0则退出死循环。
作者: carpcarey    时间: 2020-5-8 17:04
正确的做法就应该是
while(a==0);
作者: 黄youhui    时间: 2020-5-8 17:24
你查查看你工程里有多少变量i,a;
作者: 片机小白    时间: 2020-5-8 18:15
本帖最后由 片机小白 于 2020-5-8 19:43 编辑
carpcarey 发表于 2020-5-8 17:00
是你的问题
当a=1
则!a是对1取反

不好意思,我的 图文 两个while不一样,我举得例子是while(i)初值是1;用中断使i 变成0 ,然后退出.而图片中的是while(!a),图中的a的初值是0.图中未显示的中断是使a = 1 ,从而使 while(!a)退出,但是图中很明显看到 右下的a 已经变成1了 但是循环while(!a)没有退出
作者: 片机小白    时间: 2020-5-8 20:45
黄youhui 发表于 2020-5-8 17:24
你查查看你工程里有多少变量i,a;

你看下 那个编译的汇编代码,在最上面0x0800094C 和0x08000094E 两条之间死循环了,和 i a 都无关了,所以我才说是编译器的bug,就是说寄存器R0 的值在这个循环里已经没有机会改变了,这才是问题,而按照我写的C语言的逻辑 应该有机会跳出循环的...我就想知道,怎么绕过这个bug
作者: carpcarey    时间: 2020-5-9 09:17
片机小白 发表于 2020-5-8 18:15
不好意思,我的 图文 两个while不一样,我举得例子是while(i)初值是1;用中断使i 变成0 ,然后退出.而图片中 ...

a=1 那 !a=0xfffe while(!a)怎么退出?
a=0 则!a=0xffff while(!a)怎么退出?
图片中的while当然不会退出,除非 a=0xffff 则!a=0x0000 while(!a)才会退出。

至于第一个whil(i) 这个i是全局变量还是局部变量?
作者: 片机小白    时间: 2020-5-9 14:59
carpcarey 发表于 2020-5-9 09:17
a=1 那 !a=0xfffe while(!a)怎么退出?
a=0 则!a=0xffff while(!a)怎么退出?
图片中的while当然不会退 ...

老哥,我直接试了while(!1);
就是直接退出循环的.. 所以当a=1时 !a = 0xfffe while(!a)应该要退出的吧,我推断错吧这个逻辑。可以看到图片中 While(!1)就连断点的空间都没了 我也测试了 while(!a)也正常退出 实践就是可以退出的。
作者: carpcarey    时间: 2020-5-10 20:07
你的优化方式?不进行代码优化看看?我看到int a=1;这行被优化了。
不行你用Volatile修饰下看看。volatile int a;
作者: 权威人物    时间: 2020-5-11 14:29
你把调试断点设在中断,看看有没有进去,再一步步调到变量的改变,看看哪一步出问题了

作者: 片机小白    时间: 2020-5-16 09:54
carpcarey 发表于 2020-5-10 20:07
你的优化方式?不进行代码优化看看?我看到int a=1;这行被优化了。
不行你用Volatile修饰下看看。volatil ...

对,您说对了,就是忘记用Volatile了,多谢老哥了。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1