KEILC优化详细分析

上传人:san****glu 文档编号:33315391 上传时间:2018-02-14 格式:DOC 页数:3 大小:25.50KB
返回 下载 相关 举报
KEILC优化详细分析_第1页
第1页 / 共3页
KEILC优化详细分析_第2页
第2页 / 共3页
KEILC优化详细分析_第3页
第3页 / 共3页
亲,该文档总共3页,全部预览完了,如果喜欢就下载吧!
资源描述

《KEILC优化详细分析》由会员分享,可在线阅读,更多相关《KEILC优化详细分析(3页珍藏版)》请在金锄头文库上搜索。

1、Keil C51总线外设操作问题的深入分析阅读了单片机与嵌入式系统应用2005年第10期杂志经验交流栏目的一篇文章Keil C51对同一端口的连续读取方法(原文) 后,笔者认为该文并未就此问题进行深入准确的分析 文章中提到的两种解决方法并不直接和简单。笔者认为这并非是 Keil C51中不能处理对一个端口进行连续读写的问题,而是对 Kei1 C51的使用不够熟悉和设计不够细致的问题,因此特撰写本文。本文中对原文提到的问题,提出了三种不同于原文的解决方法。每种方法都比原文中提到的方法更直接和简单,设计也更规范。(无意批评,请原文作者见谅)1 问题回顾和分析原文中提到:在实际工作中遇到对同一端口反

2、复连续读取,Keil C51编译并未达到预期的结果。原文作者对 C 编译出来的汇编程序进行分析发现,对同一端口的第二次读取语句并未被编译。但可惜原文作者并未分析没有被编译的原因,而是匆忙地采用一些不太规范的方法试验出了两种解决办法。对此问题,翻阅 Keil C51的手册很容易发现:KeilC51的编译器有一个优化设置,不同的优化设置,会产生不同的编译结果。一般情况缺省编译优化设置被设定为8级优化,实际最高可设定为9级优化:1. Dead code elimination。2.Data overlaying。3.Peephole optimization。4.Register variables

3、。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优化编译理所当然认为重复读第二次是没有用的,直

4、接用第一次读取的结果就可以了,因此编译器跳过了第二条读取语句。至此,问题就一目了然了。2 解决方法由以上分析很容易就能提出很好的解决办法。21 最简单最直接的办法程序一点都不用修改,将 Keil C51的编译优化选择设置为0(不优化) 就可以了。选择project 窗口的 Target,然后打开“Options for Target”设置对话框,选择“C51”选项卡,将“Code Optimiztaion”中的“Level”选择为 “0:Costant folding”。再次编译后,大家会发现编译结果为:CLR MAXHBENMOV DPTR,#MAX197MOVX A,DPTRMOV R7,

5、AMOV down8,R7SETB MAXHBENMOV DPTR,#MAX197MOVX A,DPTRMOV R7,AMOV up4,R7两次读取操作都被编译出来了。22 最好的方法告诉 Keil C51,这个地址不是一般的扩展 RAM,而是连接的设备 ,具有“挥发” 特性,每次读取都是有意义的。可以修改变量定义,增加“volatile”关键字说明其特征:unsigned char volatile xdata MAX197 _at_ 0x8000;也可以在程序中包含系统头文件;“#include”,然后在程序中修改变量,定义为直接地址:#define MAX197 XBYTE0x8000这

6、样,Keil C51的设置仍然可以保留高级优化,且编译结果中,同样两次读取并不会被优化跳过。2 3 硬件解决方法原文中将 MAX197的数据直接连接到数据总线,而对地址总线并未使用,采用一根端口线选择操作高低字节。很简单的修改方法就是使用一根地址线选择操作高低字节即可。比如:将 P20(A8)连接到原来 P10连接的 HBEN 脚(MAX197的5脚)在程序中分别定义高低字节的操作地址:unsigned char volatile xdata MAX197_L _at_ 0x8000;unsigned char volatile xdata MAX197_H _at_ 0x8100;将原来的程

7、序:MAXHBEN =0;down8=MAX197;/读取低8位MAXHBEN =1;up4=MAX197;/读取高4位改为以下两句即可down8= MAX197_L;/读取低 8位up4=MAX197_H;/读取高4位3 小结Keil C51经过长期考验和改进以及大量开发人员的实际使用,已经克服了绝大多数的问题,并且其编译效率也非常高。对于一般的使用很难再发现什么问题。笔者曾经粗略研究过一下 Keil C51优化编洋的结果非常佩服 Keil C51设计者的智慧,一些 C 程序编译产生的汇编代码甚至比一般程序员直接用汇编编写的代码还要优秀和简练 通过研读 Kell C51编译产生的汇编代码对提

8、高汇编语言编写程序的水平都是很有帮助的。由本文中的问题可以看出:在设计中遇到问题时一定不要被表面现象蒙蔽,不要急于解决,应该认真分析,找出问题的原因这样才能从根本上彻底解决问题。附表:Keil C51中的优化级别及优化作用级别 说明0常数合并:编译器预先计算结果,尽可能用常数代替表达式。包括运行地址计算。优化简单访问:编译器优化访问8051系统的内部数据和位地址。跳转优化:编译器总是扩展跳转到最终目标,多级跳转指令被删除。1死代码删除:没用的代码段被删除。拒绝跳转:严密的检查条件跳转,以确定是否可以倒置测试逻辑来改进或删除。2数据覆盖:适合静态覆盖的数据和位段被确定,并内部标识。BL51连接/

9、定位器可以通过全局数据流分析,选择可被覆盖的段。3窥孔优化:清除多余的 MOV 指令。这包括不必要的从存储区加载和常数加载操作。当存储空间或执行时间可节省时,用简单操作代替复杂操作。4寄存器变量:如有可能,自动变量和函数参数分配到寄存器上。为这些变量保留的存储区就省略了。优化扩展访问:IDATA、XDATA 、PDATA 和 CODE 的变量直接包含在操作中。在多数时间没必要使用中间寄存器。局部公共子表达式删除:如果用一个表达式重复进行相同的计算,则保存第一次计算结果,后面有可能就用这结果。多余的计算就被删除。Case/Switch 优化:包含 SWITCH 和 CASE 的代码优化为跳转表或跳转队列。5全局公共子表达式删除:一个函数内相同的子表达式有可能就只计算一次。中间结果保存在寄存器中,在一个新的计算中使用。简单循环优化:用一个常数填充存储区的循环程序被修改和优化。6 循环优化:如果结果程序代码更快和有效则程序对循环进行优化。7 扩展索引访问优化:适当时对寄存器变量用 DPTR。对指针和数组访问进行执行速度和代码大小优化。8 公共尾部合并:当一个函数有多个调用,一些设置代码可以复用,因此减少程序大小。9 公共块子程序:检测循环指令序列,并转换成子程序。Cx51甚至重排代码以得到更大的循环序列。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号