5094|10

57

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教 keil c 中 代码优化的问题 [复制链接]

请问KEIL C  中代码大小的优化 有什么好方法呢?
函数中局部变量的定义顺序怎么样才是最优的?
为什么函数中的一些代码顺序不一样也会造成很大的空间变化?

最新回复

环境keil uVserion3, memory model选择 large:variables in xdata的时候出现如下情况 static unsigned int ADC0_result[9] function () { unsigned int kk; int temp0; int temp1; unsigned char i; ... for(i=0;i > 4;   temp1 = temp1 < < 4;   kk=temp1+temp0;   ADC0_reslut=kk; } } 调试发现如果 i=0 temp0=AD0SL----->temp0=0x00a0 temp1=AD0SH----->temp1=0x0090 temp0=temp0>>4----->temp0=0x000a temp1=temp1 < temp1=0x0900 kk=temp1+temp0----->kk=0x090a 但是 ADC0_result[0]=kk----->ADC0_result[0]=0x0a0a  这一句赋值不正确!!!找不到原因,类型都是正确的。 为什么0x090a会变成0x0a0a 把高位换成了低位? 更奇怪的是运行调试中,Delay_ms(100);运行好,temp1的值会莫名其妙变化,但其实没有操作!! 怎么这么奇怪,但是memory mode选择 small正常  详情 回复 发表于 2008-9-28 23:19
点赞 关注

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
优化要针对不同的需求和不同的代码。空讲是没法说清楚的。
局部变量的定义顺序不重要,而要和其使用联系起来才行。如果根本就没有被使用,随便你怎么定义都行。
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
我改变了下变量的顺序 ,结果代码大小改变了
例如:BYTE  i;
     WORD   j;
变成:  WORD   j;
      BYTE  i;


还有就是函数的形参顺序变了,代码大小也改变
例如:void fun(BYTE i,WORD j,DWORD k)  变成  void fun(DWORD k, BYTE i,WORD j)

更搞笑的是  我发现我函数里有个局部变量没用 于是就删了它   结果代码大小变了    增加了100多B

还有就是函数里面的句子 前后换下位置  代码大小也变了  

我主要是想优化代码的大小,结果发现很多奇怪的现象,应该是我对编译原理不懂吧~~~


希望各位指教指教阿,呵呵 无限感谢~~~
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

4
 
这个……太夸张了吧。你的代码很有个性,可能每个字符都给你落了号了,随便改改都有严重的后果。少见少见。
方便的话,把代码贴出来,可以一起分析。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

5
 
比如说:
void fun(BYTE i,WORD j,DWORD k)  
{

k=i+j;

}

变成
void fun(DWORD k, BYTE i,WORD j)
{
k=i+j;
}



void fun(DWORD k,WORD j ,BYTE i)
{
k=i+j;
}

虽然不是我实际开发的代码,但是类似,您可以试一下~~~
十分感谢您的关注,呵呵~~
 
 
 

回复

91

帖子

0

TA的资源

一粒金砂(初级)

6
 
keil C的C编译涉及的函数参数传递去看看,可以解决这个方面的疑问。
简单的说:参数传递涉及寄存器和堆栈,寄存器和堆栈都是8bit的,而DWORD是32bit的,放在前面,有两个寄存器不需要读进来,放在后面,就得读4次堆栈。
慢慢看吧,有这个提示也该够了。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

7
 
51单片机中的参数传递不是用堆栈哦。哈佛结构的CPU内部RAM非常少,没有办法用堆栈做参数传递和局部变量空间。所以传递参数和申明局部变量都需要用到数据段。Small模式下默认使用内部数据段、Large模式下默认使用外部数据段。因为用来传递参数的寄存器数量有限,如果你的函数参数的实际大小超出了寄存器传递的极限(你上面说的那个函数就属于参数太多的情况),那编译器就会自动找一块内存(外部或内部的)空间来做参数传递。

编译器为了节约内存消耗量,会根据程序流程来重用内存空间,把不冲突的函数中的变量定义到同一个地址中去。例如,如果函数A和函数B永远都不会同时使用,那A和B用到的局部变量空间就是可以重叠的。也就是说Keil在处理变量的时候是非常复杂的,具体结果和你的实际程序流程相关。具体怎么回事很难说清楚。

要真的说优化原则我也不知道,我感觉就是根据自己对51芯片的理解,以及实际的代码情况,可以手动的做些微调。所以要做优化,必须要理解51单片机的体系结构。

引用 5 楼 shuiyan 的回复:
keil C的C编译涉及的函数参数传递去看看,可以解决这个方面的疑问。
简单的说:参数传递涉及寄存器和堆栈,寄存器和堆栈都是8bit的,而DWORD是32bit的,放在前面,有两个寄存器不需要读进来,放在后面,就得读4次堆栈。
慢慢看吧,有这个提示也该够了。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

8
 
进行请教各位:
我改变了下变量的顺序 ,结果代码大小改变了 :
例如: BYTE  i=0;
     WORD  j=0;
     DWORD  K=0;
     k=i+j;

变成:  
     DWORD  K=0;
     WORD  j=0;
     BYTE  i=0;
     k=i+j;

或:
     WORD  j=0;
     BYTE  i=0;
     DWORD  K=0;
     k=i+j;


为什么代码都一样,可是代码大小却不一样呢????呵呵多谢了

 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

9
 
楼主要好好学习一下微机原理和单片机原理才能真正明白为什么。

首先,在一般微机里头,程序的局部变量都是存放在堆栈中,变量的顺序影响的只是变量在堆栈中的位置,堆栈中的数据在函数运行的过程中是函数独享的,改变变量的顺序对程序而言是没有多大影响的。

而51单片机的局部变量是存放在编译器指定的某个和其它函数的局部变量共用的内存空间中。这些变量存放的地方不是某个函数独享的,要和其它所有函数共用的,共用的原则就是在调用这个函数的时候,共用变量内存空间的函数不会被调用到。你的变量顺序的调整会影响到编译器对所有函数变量空间的分配,变量的顺序影响大了去啦。

另外编译器还会根据你的代码流程来删除多余代码、合并代码、将共性的处理生成函数等等操作。

你如果真想仔细看看编译器优化到底做了什么,不如写一个简单的程序,编译生成汇编代码来研究(生成的代码好像在“.m51”文件中)。
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

10
 
其实,这些问题直接看编译的汇编代码最有效,因为你能直接看出编译器做了什么动作。
另外,这种变化是跟编译器直接相关的,换一个编译器,结果就会完全不一样。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

11
 
环境keil uVserion3, memory model选择 large:variables in xdata的时候出现如下情况

static unsigned int ADC0_result[9]

function ()
{
unsigned int kk;
int temp0;
int temp1;
unsigned char i;
...
for(i=0;i <9;i++){
  Delay_ms(100);  //停顿100毫秒
  temp0 = AD0SL  //AD0SL是寄存器
  temp1 = AD0SH  //AD0HL是寄存器
  temp0 = temp0 >> 4;
  temp1 = temp1 < < 4;
  kk=temp1+temp0;
  ADC0_reslut=kk;
}
}

调试发现如果
i=0
temp0=AD0SL----->temp0=0x00a0
temp1=AD0SH----->temp1=0x0090
temp0=temp0>>4----->temp0=0x000a
temp1=temp1 < <4----->temp1=0x0900
kk=temp1+temp0----->kk=0x090a
但是
ADC0_result[0]=kk----->ADC0_result[0]=0x0a0a  这一句赋值不正确!!!找不到原因,类型都是正确的。

为什么0x090a会变成0x0a0a 把高位换成了低位?

更奇怪的是运行调试中,Delay_ms(100);运行好,temp1的值会莫名其妙变化,但其实没有操作!!

怎么这么奇怪,但是memory mode选择 small正常
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表