Keil的代码优化产生的问题

Keil的代码优化产生的问题

转载这篇文章的原因:

今天和昨天一直为一个BUG困扰,明明我有写程序语句(还是很关键的那种),为什么keil不会生成响应的汇编语句。

 


看见132的红色断电没
132下一句应该运行133
但是下一句直接运行了135
好像133和134不存在一样 

 

 

转载内容如下:

 

Keil的代码优化产生的问题

 

 

阅 读了《单片机与嵌入式系统应用》2005年第10期杂志《经验交流》栏目的一篇文章《Keil C5l对同一端口的连续读取方法》(原文)后,笔者认为该文并未就此问题进行深入准确的分析。文章中提到的两种解决方法并不直接和简单。笔者认为这并非是 Keil C51中不能处理对一个端口进行连续读写的问题,而是对Keil C51的使用不够熟悉和设计不够细致的问题,因此特撰写本文。

本文中对原文提到的问题,提出了三种不同于原文的解决方法。每种方法都比原文中提到的方法更直接和简单,设计也更规范。(无意批评,请原文作者见谅)

1 问题回顾和分析

原文中提到:在实际工作中遇到对同一端口反复连续读取,Keil C5l编译并未达到预期的结果。原文作者对C编译出来的汇编程序进行分析发现,对同一端口的第二次读取语句并未被编译。但可惜原文作者并未分析没有被编译 的原因,而是匆忙地采用一些不太规范的方法试验出了两种解决办法。

对此问题,翻阅Keil C51的手册很容易发现:KellC51的编译器有一个优化设置,不同的优化设置,会产生不同的编译结果。一般情况缺省编译优化设置被设定为8级优化,实际最高可设定为9级优化:

①Dead code elimination。

②Data overlaymg。

③Peephole optimization。

④Register variables。

⑤Common subexpression elimination。

⑥Loop rotation。

⑦Extended Index Access 0ptimizing。

⑧Reuse Common。Entry Code。

⑨Common Block Subroutines。

而以上的问题,正是由于KeiI C5l编译优化产生的。因为在原文程序中将外设地址直接按如下定义:

unsigned char xdata MAXl97_at_Ox8000;

采用_at_将变量MAXl97定义到外部扩展RAM指定地址Ox8OOO。因此,Keil C51优化编译理所当然认为重复读第二次是没有用的,直接用第一次读取的结果就可以了,因此编译器跳过了第二条读取语句。至此,问题就一目了然了。

2 解决方法

由以上分析很容易就能提出很好的解决办法。

2.1 最简单最直接的办法

程序一点都不用修改,将Keil C5l的编译优化选择设置为0(不优化)就可以了。

选择project窗口的Target,然后打开“Options forTarget”设置对话框,选择“C5l”选项卡,将“Code Optimiztaion”中的“Level”选择为“0:Costant folding”。再次编译后,大家会发现编译结果为:

CLR MAXHBEN

MOV DPTR,#M.AXl97

MOVX A,@DPTR

MOV R7.A

MOV down8.R7

SETB MAXHBEN

MOV DPTR,#MAXl97

MOVX A,@DPTR

MOV R7.A

MOV uD4.R7

两次读取操作都被编译出来了。

2.2 最好的方法

告诉Keil C51,这个地址不是一般的扩展RAM,而是连接的设备,具有“挥发”特性,每次读取都是有意义的。

可以修改变量定义,增加“volatile”关键字说明其特征:

unsigned char volatile xdata MAXl97_at_Ox8000;

也可以在程序中包含系统头文件:“#incIude”,然后在程序中修改变量,定义为直接地址:

#defme MAXl97 XBYTE[Ox8000]

这样,。Keil C51的设置仍然可以保留高级优化,且编译结果中,同样两次读取并不会被优化跳过。

2.3 硬件解决方法

原文中将MAXl97的数据直接连接到数据总线,而对地址总线并未使用,采用一根端口线选择操作高低字节。很简单的修改方法就是使用一根地址线选择操作高 低字节即可。比如:将P2.0(A8)连接到原来P1.O连接的HBEN脚(MAXl97的5脚),在程序中分别定义高低字节的操作地址:

unsigned char volatile xdata MAXl97_L_aI_Ox8000;

unsigned char volatile xdata MAXl97 H at 0.x8100;

将原来的程序:

MAXHBEN=O; //读取低8位

down8=MAXl97:

MAXHBEN=1; //读取高4位

up4=MAXl97:

改为以下两句即可:

down8=MAXl97_L; //读取低8位

up4=MAXl97_H; //读取高4位

3 小结

Keil C51经过长期考验和改进以及大量开发人员的实际使用,已经克服了绝大多数的问题,并且其编译效率也非常高。对于一般的使用,很难再发现什么问题。笔者曾 经粗略研究过一下Keil C51优化编译的结果,非常佩服Keil C51设计者的智慧,一些C程序编译产生的汇编代码,甚至比一般程序员直接用汇编编写的代码还要优秀和简练。通过研读KeilC51编译产生的汇编代码, 对提高汇编语言编写程序的水平都是很有帮助的。

由本文中的问题可以看出:在设计中遇到问题时,一定不要被表面现象蒙蔽,不要急于解决。应该认真分析,找出问题的原因,这样才能从根本上彻底解决问题。上不会出现不必要的干扰,防止了数据不一致的发生。

 

附表: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甚至重排代码以得到更大的循环序列

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Keil5代码整理项目文件插件是一种工具,可以帮助开发人员更方便地整理和管理Keil5工程中的源代码文件。 该插件的功能非常强大。首先,它可以自动识别和归类项目中的源代码文件,例如C语言源文件、头文件、汇编文件等,然后将它们按照一定规则整理到相应的文件夹中。这样,开发人员可以更快速地找到和编辑他们所需要的代码文件,提高开发效率。 其次,该插件还可以自动检测项目中的重复代码,对其进行合并或剔除,避免代码冗余。这对于项目的优化和维护非常重要,能够减少程序体积,提高项目的可读性和可维护性。 此外,该插件还可以自动生成代码注释。通过分析代码的结构和功能,它可以生成规范的注释,包括函数的描述、输入输出参数的说明等。这对于代码的可理解性和可维护性非常有帮助。 最后,该插件还具备自动格式化代码的能力。它可以根据统一的代码风格规则,将项目中的代码按照一定的缩进、换行、空格等格式进行统一处理,使得代码整齐、易读。这对于团队合作开发特别重要,能够减少不必要的冲突和调整。 综上所述,Keil5代码整理项目文件插件是一款非常实用的工具,可以帮助开发人员更好地管理和维护项目中的源代码文件,提高开发效率和代码质量。 ### 回答2: Keil5代码整理项目文件插件是一种用于Keil5开发环境的工具,可帮助开发者整理项目文件并提高代码的可读性和维护性。该插件提供了一系列功能,以下将详细介绍它的主要特点和功能。 首先,Keil5代码整理项目文件插件可以帮助开发者创建代码模块和各种源文件,使项目结构更加清晰有序。通过该插件,开发者可以自动添加和删除文件,包括头文件、源文件、配置文件等,简化了文件管理和维护的过程。 其次,该插件可以帮助开发者对代码进行格式化和优化。通过一键操作,开发者可以自动对代码进行缩进、换行、空格等格式方面的调整,使代码结构更加美观易读。同时,插件还可以对代码进行静态检查,帮助开发者发现潜在的错误和问题,并提供相应的建议和修复选项。 另外,该插件还提供了源文件的导入和导出功能,方便开发者在不同的项目之间共享和复用代码。通过导入功能,开发者可以将已有的代码文件导入到当前项目中,避免重复编写相似的代码。通过导出功能,开发者可以将当前项目中的代码文件导出到其他项目中,提高代码复用性和开发效率。 总之,Keil5代码整理项目文件插件是一款功能强大且易于使用的工具,它可以帮助开发者优化项目文件结构、格式化代码、进行静态检查和导入导出代码,提高代码质量和开发效率。无论是初学者还是资深开发者,都可以从中受益并提升开发体验。 ### 回答3: Keil5代码整理项目文件插件是一种用于Keil MDK集成开发环境的软件工具。该插件的主要功能是帮助开发者对代码进行整理和优化,以提高代码的可读性和维护性。 首先,该插件可以对项目中的源代码进行自动格式化。通过识别代码的结构和语法,插件可以将代码按照统一的风格进行排版和缩进,使其更加清晰易读。这有助于团队协作和代码审查的进行,提高了代码编写的一致性和效率。 其次,插件还可以自动检测代码中的潜在问题和错误。通过静态分析和代码规范检查,插件能够发现常见的编程错误和潜在的逻辑问题,如未使用的变量、未关闭的文件指针等。这种自动检测的功能有助于提前发现和修复问题,避免在程序运行时产生错误和异常。 此外,插件还提供了一些代码重构的功能。开发者可以使用这些功能快速地重命名变量、函数和文件名,进行函数提取、内联、提取接口等常用的重构操作。这些重构操作可以提高代码的模块化和可维护性,减少代码冗余和重复。 最后,该插件还支持代码注释的生成和维护。开发者可以使用插件自动生成函数和类的注释模板,并根据需要进行修改和补充。注释的生成和维护有助于增加代码的可读性和理解性,方便后续的维护和升级工作。 综上所述,Keil5代码整理项目文件插件提供了一系列的功能和工具,可以帮助开发者优化代码质量、提高开发效率和减少错误。在开发过程中使用该插件可以提高代码的可读性和可维护性,为项目的顺利进行提供有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值