找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4465|回复: 5
收起左侧

IAR 8051 太聪明了

[复制链接]
ID:91350 发表于 2015-10-29 00:36 | 显示全部楼层 |阅读模式
    今晚真是个不眠之夜啊,很久没用C++对单片机编程了,而且以前一直在用IAR For AVR编程,现在用IAR 8051来写STC的程序,一直都是开最高优化级别,没发现问题过.今天发现了一个苦B的问题.我在全局定义了一个bool变量,在定时器中断函数里改变它的值,然后主程序判断这个值来确定是否进入空闲模式.可是一开优化,马上变味了.打开反编译软件查看生成的代码,一个while()的循环竟然变成了死循环,无论怎么改变C语法都无法改变生成的结果.想到以前在写Microsoft C++程序的时候用到过一个关键字:volatile , 意思是容易被意想不到改变的变量.添加在变量的声明以后,while循环回来了.IAR编译器我真是越来越喜欢了.虽然有时程序会莫名其妙的走样,可是它的代码优化方面还是无可比拟的.
C++原程序:volatile bool bStart;
      while(bStart == 0)
         PCON_bit.IDL = 1;//                进入空闲模式
意思是如果没有程序改变bStart这个变量的话,CPU就继续休息.如果有程序改变的话就退出循环执行一次主函数.
在没加volatile时生成的汇编代码:

Q022C:             ORL   PCON,#01H
                         SJMP  Q022C
坏了,while 循环影子都没了

声明volatile后的代码:

Q0225:      MOV   R0,#56H
                   MOV   A,@R0
                   JZ    Q022D
                   LJMP  Q0196
;===========================================
Q022D:       ORL   PCON,#01H
                   SJMP  Q0225

这回它判断@R0里的变量值了,56H里的值就是bStart,可爱的sjmp指令也回来了.

好在以前还学习过Microsoft的编程,IAR编译器才是真正的标准C编译器,比那些KEIL,ICC好多了,只要我们写程序的时候严谨些,知道CPU这个时候会干什么, 就可以写出漂亮的程序.
回复

使用道具 举报

ID:791413 发表于 2021-7-27 16:22 | 显示全部楼层
21年学keil的路过,c的编译器应该是早就能volatile了
回复

使用道具 举报

ID:883242 发表于 2021-7-27 21:15 | 显示全部楼层
IAR测试过,吊打一切编译器,包括在ARM平台上面吊打ARM亲儿子RealView编译器。

但是在8051这个平台上,IAR效率是不如Keil C51的。

Keil C51认为它的用户都是不懂volatile这个关键字的傻子,所以写不写volatile都可以得到想要的结果。
回复

使用道具 举报

ID:192294 发表于 2022-4-21 14:32 | 显示全部楼层
用过Keil C51的用户应该都知道volatile。这个与优化级别有关。优化高而不加volatile一样会优化忽略掉。


(2830)
回复

使用道具 举报

ID:1101997 发表于 2023-12-2 08:49 | 显示全部楼层
这是嵌入式和正常C的区别,KEIL默认变量你会在其他地方去改变它,所以一般并不需要使用volatile。
回复

使用道具 举报

ID:195496 发表于 2023-12-2 17:45 | 显示全部楼层
楼上说的有道理
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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