- 26
- 9月
最近,Hanny使用了一段时间的IAR,很是郁闷。总结一下IAR的郁闷之旅吧。
首先,就是版本间的兼容问题了。我在机子上同时装了IAR720H和IAR750A,没想到工程却不能互相兼容,720H的工程一旦升级成750的工程后,就不能回来了。这不禁让我想起了VC6和VC.NET的关系。不过VC6和VC.NET还好我们可以建不同版本的工程,然后用不同的方式打开就行了。IAR却不行!我在IAR工程文件的打开方式中添加了两个版本的打开方式,可是每次是都被它自作聪明地改成了一个!唉,现在只能先运行不同版本的IDE,然后再分别打开工程了。烦!
然后,就是使用上的问题了。一量按错快捷键,就会在程序里加一些莫名其妙的符合,最后结果就是编译不通过。所以,当IAR提示你某一行编译不过,你又看不出有什么错误时,注意看看行尾是不是被添加了一些“看不见”的符号。
接下来就是IAR编译方面的问题了。第一个就是:IAR似乎不支持JB和JNB的汇编指令?或许有,我不知道。反正我在其汇编代码中看到的都是先MOV到C,然后再用JC和JNC。这样,每一处跳跳转都得多出一Byte指令和一个周期呀!
第二点就是:char默认为unsigned char 而不是signed char。char可以设默认类型,相对于其它IDE来说,这确是一件好事。但是你不能默认为unsigned型的呀!好歹也应该是signed型的,这样才比较符合大家习惯。不过这点还好,反正一般来说,我都不会直接用char或unsigned char的。一般都用s8和u8,只要在typedef时注意一下就行了。
第三点就是:IAR在使用虚拟寄存器时,会保护虚拟寄存器。它的做法是:先MOV A一个需要保护的寄存器的个数,然后再调用它的虚拟寄存器压栈函数。在虚拟寄存器少于四个时,它会直接进行几次PUSH,而不会使用函数调用。可是我在使用过程中却发现,有时只有两个虚拟寄存器,它却先MOV A, #2,再调用它的压栈函数?呃,不懂。。。
第四点就是:在函数头尾,有时会出现一些莫名的R6的PUSH和POP操作。函数中间,有时又会无端的把值赋给A?没做深入研究。
第五点就是:函数进行short型返回值时,不会直接赋值到R2,R3,而是先到DPH,DPL再到R2,R3,多此一举。不知怎么去掉它。
第六点就是:我比较不爽第五点的做法,决定手动将变量直接嵌汇编来MOV到R2和R3。比较夸张的是:它竟然将asm(MOV R)优化成nop!! 这。。。你也不能乱判我这两句嵌汇编没用呀!
第七点就是:在一些中断中根本没使用R寄存器,但是在设置了RBank后,也会去对PSW进行R寄存器切Bank操作。有点多余吧?
第八点就是:部份sfr为8的倍数的寄存器不能直接使用C语言来操作,只能嵌汇编。这一点可能是我哪里没弄好吧,迟些再找找原因。
第九点就是:经常会将一些它自以为没用的代码删除,有时都是很致命的。所以,很多变量尽量都定义成volatile型。中断会使用的一定要,这一点就不用说了。往往容易忽略的是DMA时使用的Buffer,一定要使用volatile!否则编译器觉得这段Ram内容不变,没准就优化就什么乱子了。
第十点就是将优化等级设成最高的size这种情况了。本来简单的程序,两句汇编就能实现的功能,硬是JMP了一大圈才实现。这一点暂不怪它,毕竟要做size优化。但是,有时JMP也太夸张点了吧。
第十一点优化等级同第十点。它竟然把中断入口嵌入的asm的PUSH指令优化成函数了!不能因为我每个中断入口都PUSH,你就优化成函数呀!你一个Call过去,再来个PUSH,接下来一个华丽的RET,程序不跑飞才见鬼了呢。
最后就是,我想让它别优化这个asm,但它却不支持volatile asm。
总之,这是一段郁闷的IAR之旅。当然,IAR还是有它的优点,至少它在一些空间的分配上要自由些,编译过程我们可以控制到更多的东西。Keil在这一方面显得没那么灵活些。但是,在经历了这一段时间后,我觉得,我还是回Keil吧,IAR感觉还是有些靠不住。写程序写得提心吊胆的,经常要看看汇编有没有出乱子,确实够累的。当然,由于Hanny也不是很熟悉IAR的使用,以上纯属个人拙见。
写得这么深奥
博主很牛x