opc++fans.com/tags/德州仪器/’ target=’_blank’ class=’arckwlink_hide’>TIon -》 c/c++ -》 language/code genderaTIon -》 opTImizaTIon选项下的优化等级
优化等级阐明(仅供参考):
则其间的 Code Optimization 栏便是用来设置C51的优化等级。共有9个优化等级(书上这么写的),高优化等级中包括了前面一切的优化等级。现将各个等级阐明如下:
0级优化:
1、常数折叠:只需有或许,编译器就执即将表达式化为常数数字的核算,其间包括运转地址的核算。
2、简略拜访优化:对8051体系的内部数据和位地址进行拜访优化。
3、跳转优化:编译器总是将跳转延至最终目标上,因而跳转到跳转之间的指令被删去。
1级优化:
1、死码消除:无用的代码段被消除。
2、跳转否决:依据一个测验回溯,条件跳转被仔细查看,以决议是否能够简化或删去。
2级优化:
1、数据掩盖:适于静态掩盖的数据和位段被辨别并符号出来。衔接定位器BL51经过对大局数据流的剖析,挑选可静态掩盖的段。
3级优化:
1、“窥孔”优化:将冗余的MOV指令去掉,包括不必要的从存储器装入目标及装入常数的操作。别的假如能节约存储空间或许程序履行时刻,杂乱操作将由简略操作所替代。
4级优化:
1、寄存器变量:使主动变量和函数参数尽或许坐落作业寄存器中,只需有或许,将不为这些变量保存数据存储器空间。
2、扩展拜访优化:来自IDATA、XDATA、PDATA和CODE区域的变量直接包括在操作之中,因而大大都时分没有必要将其装入中心寄存器。
3、部分公共子式消除:假如表达式中有一个重复履行的核算,第一次核算的成果被保存,只需有或许,将被用作后续的核算,因而可从代码中消除冗杂的核算。
4、CASE/SWITCH句子优化:将CASE/SWITCH句子作为跳转表或跳转串优化。
5级优化:
1、大局公共子式消除:只需有或许,函数内部相同的子表达式只核算一次。中心成果存入一个寄存器以替代新的核算。
2、简略循环优化:以常量占有一段内存的循环再运转时被优化。
6级优化:
1、回路循环:假如程序代码能更快更有用地履行,程序回路将进行循环。
7级优化:
1、扩展进口优化:在合适时对寄存器变量运用DPTR数据指针,指针和数组拜访被优化以减小程序代码和进步履行速度。
8级优化:
1、公共尾部兼并:对同一个函数有多处调用时,一些设置代码可被重复运用,然后减小程序代码长度。
9级优化:
1、公共子程序块:检测重复运用的指令序列,并将它们转换为子程序。C51乃至会重新安排代码以取得更多的重复运用指令序列。
当然,优化等级并非越高越好,应该依据具体要求恰当挑选。
Keil C51总线外设操作问题的深化剖析
阅读了《单片机与嵌入式体系运用》2005年第10期杂志《经验交流》栏目的一篇文章《Keil C51对同一端口的接连读取办法》(原文)后,笔者以为该文并未就此问题进行深化精确的剖析 文章中说到的两种解决办法并不直接和简略。笔者以为这并非是Keil C51中不能处理对一个端口进行接连读写的问题,而是对Kei1 C51的运用不行了解和规划不行详尽的问题,因而特编撰本文。
本文中对原文说到的问题,提出了三种不同于原文的解决办法。每种办法都比原文中说到的办法更直接和简略,规划也更标准。
1 问题回忆和剖析
原文中说到:在实践作业中遇到对同一端口重复接连读取,Keil C51编译并未到达预期的成果。原文作者对C编译出来的汇编程序进行剖析发现,对同一端口的第2次读取句子并未被编译。但惋惜原文作者并未剖析没有被编译的原因,而是匆忙地选用一些不太标准的办法实验出了两种解决办法。
对此问题,翻阅Keil C51的手册很简略发现:KeilC51的编译器有一个优化设置,不同的优化设置,会发生不同的编译成果。一般状况缺省编译优化设置被设定为8级优化,实践最高可设定为9级优化:
1. Dead code elimination。
2.Data overlaying。
3.Peephole optimization。
4.Register variables。
5.Common subexpression elimination。
6.Loop rotation。
7.Extended Index Access Optimizing。
8.Reuse Common Entry Code。
9.Common Block Subroutines。
而以上的问题,正是由于Keil C51编译优化发生的。由于在原文程序中将外设地址直接按如下界说:
unsigned char xdata MAX197 _at_ 0x8000
选用_at_将变量MAX197界说到外部扩展RAM 指定地址0x8000。因而,Keil C51优化编译天经地义以为重复读第2次是没有用的,直接用第一次读取的成果就能够了,因而编译器越过了第二条读取句子。至此,问题就一望而知了。
2 解决办法
由以上剖析很简略就能提出很好的解决办法。
2.1 最简略最直接的办法
程序一点都不必修正,将Keil C51的编译优化挑选设置为0(不优化)就能够了。挑选project窗口的Target,然后翻开“Options for Target”设置对话框,挑选“C51”选项卡,将“Code Optimiztaion”中的“Level”挑选为“0:Costant folding”。再次编译后,我们会发现编译成果为:
CLR MAXHBEN
MOV DPTR,#MAX197
MOVX A,@DPTR
MOV R7,A
MOV down8,R7
SETB MAXHBEN
MOV DPTR,#MAX197
MOVX A,@DPTR
MOV R7,A
MOV up4,R7
两次读取操作都被编译出来了。
2.2 最好的办法
告知Keil C51,这个地址不是一般的扩展RAM,而是衔接的设备,具有“蒸发”特性,每次读取都是有意义的。能够修正变量界说,添加“volatile”关键字阐明其特征:
unsigned char volatile xdata MAX197 _at_ 0x8000;
也能够在程序中包括体系头文件;“#include”,然后在程序中修正变量,界说为直接地址:
#define MAX197 XBYTE
这样,Keil C51的设置依然能够保存高档优化,且编译成果中,相同两次读取并不会被优化越过。
附表:Keil C51中的优化等级及优化效果 等级 阐明
0 常数兼并:编译器预先核算成果,尽或许用常数替代表达式。包括运转地址核算。
优化简略拜访:编译器优化拜访8051体系的内部数据和位地址。
跳转优化:编译器总是扩展跳转到最终目标,多级跳转指令被删去。
1 死代码删去:没用的代码段被删去。
回绝跳转:紧密的查看条件跳转,以确认是否能够倒置测验逻辑来改善或删去。
2 数据掩盖:合适静态掩盖的数据和位段被确认,并内部标识。BL51衔接/定位器能够经过大局数据流剖析,挑选可被掩盖的段。
3 窥孔优化:铲除剩余的MOV指令。这包括不必要的从存储区加载和常数加载操作。当存储空间或履行时刻可节约时,用简略操作替代杂乱操作。
4 寄存器变量:如有或许,主动变量和函数参数分配到寄存器上。为这些变量保存的存储区就省掉了。
优化扩展拜访:IDATA、XDATA、PDATA和CODE的变量直接包括在操作中。在大都时刻没必要运用中心寄存器。
部分公共子表达式删去:假如用一个表达式重复进行相同的核算,则保存第一次核算成果,后边有或许就用这成果。剩余的核算就被删去。
Case/Switch优化:包括SWITCH和CASE的代码优化为跳转表或跳转行列。
5 大局公共子表达式删去:一个函数内相同的子表达式有或许就只核算一次。中心成果保存在寄存器中,在一个新的核算中运用。
简略循环优化:用一个常数填充存储区的循环程序被修正和优化。
6 循环优化:假如成果程序代码更快和有用则程序对循环进行优化。
7 扩展索引拜访优化:恰其时对寄存器变量用DPTR。对指针和数组拜访进行履行速度和代码巨细优化。
8 公共尾部兼并:当一个函数有多个调用,一些设置代码能够复用,因而削减程序巨细。
9 公共块子程序:检测循环指令序列,并转换成子程序。Cx51乃至重排代码以得到更大的循环序列。