今晚真是个不眠之夜啊,很久没用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这个时候会干什么, 就可以写出漂亮的程序.
|