keil c51编译器的一些使用心得(一)

原创 2004年03月16日 18:15:00

    本人是刚刚参加工作的学生,使用keil编译器已经半年多了,在这半年的时间里,我总结了keil的使用的一些心得,希望和大家分享一下,另外请高人点拨一下,由于我不是计算机专业的,所以对于编译原理和操作系统等高深的课程没有接触过,总是认为以下提到的一些规律都是有理论根据的,希望高人指点。
    现在的存储器已经不像七八年前那样昂贵了,但是ram相对于rom和eeprom的价格还是不可同样看待的,所以程序中节省内存在现在看来还是非常关键的。原因有以下几点:
1.ram的存取速度相对于eeprom的存取速度要快很多倍,不在一个数量级上,主要是因为eeprom的存储要想写入就必须先擦除,而且eeprom的擦出需要成块擦除(这是由于eeprom的擦除原理是场效应管的栅极上电擦除的,为了节省成本厂家一般都是8Bytes/page 64Bytes/page),所以使用ram来处理中间的数据是能够符合速度要求的。
2.无论是xram还是eeprom都是外部存储器,在负值时都要用到16bit地址空间(8位机),这样无形中就增大了程序的code的体积并且使得速度上也受到影响,所以尽量把indata区的ram用到极限是非常有意义的。

本人总结了一些节省内存的规律,提供给大家讨论一下,看看是否可行。

1.内存分配的基本原理:
keil与其他的c语言编译器我认为从内存分配的原理上是基本相同的。总结起来,其实很简单,就是选最长的路径进行编译(话糙理不糙),例如下面的两段程序
program 1:
unsigned char a();
void b();
void main()
{
 unsigned char byte1;
 unsigned char byte2;

 byte1 = byte2 = 3;

 if( a() == 3)
 {
  b();
 }

 a();

 return;
}

// a function
unsigned char a()
{
 unsigned char byte_a1;
 unsigned char byte_a2;

 byte_a1 = byte_a2 = 3;

 byte_a1 = 4;
 byte_a2 = 5;

 return byte_a1;
}

// b function
void b()
{
 unsigned char byte_b1;
 unsigned char byte_b2;
 unsigned char byte_b3;

 byte_b1 = byte_b2 = byte_b3 = 3;

 return;
}

program 2:
void a();
void b();
void main()
{
 unsigned char byte1;
 unsigned char byte2;

 byte1 = byte2 = 3;

 a();

 return;
}

// a function
void a()
{
 unsigned char byte_a1;
 unsigned char byte_a2;

 byte_a1 = byte_a2 = 3;

 if (byte_a1 == 3)
 {
  b();
 }

 byte_a1 = 4;
 byte_a2 = 5;

 return;
}

// b function
void b()
{
 unsigned char byte_b1;
 unsigned char byte_b2;
 unsigned char byte_b3;

 byte_b1 = byte_b2 = byte_b3 = 3;

 return;
}

两段程序的作用是相同的,都是先执行函数a,然后根据byte_a1的值判断去执行b程序,但是用keil编译的结果却不相同program 1 编译的结果是data:14 code:48,而program 2 编译的结果是data:16 code:56,可见program 1 比 program 2 即节省了code又节省了内存。

看一下反汇编代码,就可以了解原因了,在a函数中调用b函数,a函数定义的byte_a1和byte_a2变量没有被释放,所以program 2 的内存分配是 8(SFR) + 1(STACK) + 2(MAIN FUNC) + 2(A FUNC) + 3(B FUNC) = 16 Bytes,而program 1 的内存分配是 8(SFR) + 1(STACK) + 3(B FUNC) = 14Bytes, 由于B函数和A函数是并行的,所以节省了a函数需要的2个字节。

这样总结看来程序不要串行,应尽量并行,充分利用有限的ram资源,这样既可以使code区变小,也可以使速度变快。

2.uncalled segment 影响内存分配:
不知道大家是否发现过当存在没有调用的函数时,内存空间很有可能会溢出,这个原因其实也非常简单例如:
program 3:
void a();
void b();
void c(unsigned char byte_input);
void main()
{
 unsigned char byte1;
 unsigned char byte2;

 byte1 = byte2 = 3;

 a();

 c(3);

 return;
}

// a function
void a()
{
 unsigned char byte_a1;
 unsigned char byte_a2;

 byte_a1 = byte_a2 = 3;

 if (byte_a1 == 3)
 {
  b();
 }

 byte_a1 = 4;
 byte_a2 = 5;

 return;
}

// b function
void b()
{
 unsigned char byte_b1;
 unsigned char byte_b2;
 unsigned char byte_b3;

 byte_b1 = byte_b2 = byte_b3 = 3;

 return;
}

void c(unsigned char byte_input)
{
 unsigned char byte_c;

 byte_c = byte_input;

 return;
}

program 3 所示如果再main.c里面调用c(3)编译后data:16,而如果不调用c(3),编译后data:17,原因是调用c(3) data = 8(SFR) + 1(STACK) + 2(MAIN FUNC) + 2(A FUNC) + 3(B FUNC) = 16Bytes,而如果不调用c(3) data = 8(SFR) + 1(STACK) + 2(MAIN FUNC) + 2(A FUNC) + 3(B FUNC) + 1(C FUNC) = 17 Bytes。
所以,建议大家如果暂时不调用的函数最好屏蔽掉,以免影响整体的内存分配。

这次先写到这里吧,希望大家多和我讨论讨论,下一次我想和大家讨论一下有关keil中data_group的问题。

教你如何使KEIL中同时具有51和ARM的编译功能

大家刚开始接触ARM时,肯定是先建立开发环境。如果你用keil 时会发现,你在此基础上你如果装了51版本的编译器的话,会发现无法装ARM版本的编译器,这就会很尴尬。用了51就无法用ARM,用ARM就无...
  • phenixyf
  • phenixyf
  • 2015年07月16日 14:13
  • 6188

Keil C51编译及连接技术(覆盖技术OVERLAY)

http://www.cnblogs.com/heiyue/p/3271421.html Keil C51编译及连接技术
  • chungle2011
  • chungle2011
  • 2014年12月20日 21:22
  • 4857

Keil C51中变量和函数的绝对地址定位问题

Keil C51中变量和函数的绝对地址定位问题: 1.  变量绝对地址定位        1)    在定义变量时使用 _at_ 关键字加上地址就可.               e.g. ...
  • phenixyf
  • phenixyf
  • 2013年02月28日 09:59
  • 6257

学习心得之keil C51

上篇有提到不同的硬件平台用到的C语言也不尽相同,现详细讲讲,MSC51系列单片机的C语言特点。 相对于通用C语言,C51增加了:sfr,sfr16,sbit,bit等共4种数据类型。 1.sfr/...
  • chengshuashuacc
  • chengshuashuacc
  • 2012年02月20日 19:50
  • 1166

KEIL C51 编译器简介_

  • 2013年09月17日 15:43
  • 74KB
  • 下载

Keil C51软件的使用教程

keil uvision2 C51软件我们在前面有所介绍,是目前功能最强大的单片机c语言集成开发环境,如果您没有此软件可以从这里下载:http://www.51hei.com/keil%CF%C2%D...
  • lianchao668
  • lianchao668
  • 2013年03月28日 15:04
  • 773

Keil C51之Strings的使用

Strings在Keil中默认安排存放到code memory;使用STRING(x)可以修改默认存储位置.
  • FireStarway
  • FireStarway
  • 2017年03月18日 15:17
  • 225

使用KEIL C51实现的简单合作式多任务操作系统内核

在51单片机上实现的合作式多任务系统内核。 实现非常简单,完全C语言实现,无需汇编。每个任务最少只需要15B内存。...
  • yyx112358
  • yyx112358
  • 2017年12月22日 23:12
  • 157

KeilC51使用详解 :第五章 Keil C51库函数参考

第五章Keil C51库函数参考 C51强大功能及其高效率的重要体现之一在于其丰富的可直接调用的库函数,多使用库函数使程序代码简单,结构清晰,易于调试和维护,下面介绍C51的库函数系统。 第一节 ...
  • ConanYang
  • ConanYang
  • 2011年11月08日 18:51
  • 659

KeilC51使用详解:第一章 Keil C51开发系统基本知识

第一章 Keil C51开发系统基本知识 第一节 系统概述 Keil C51是美国KeilSoftware公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性...
  • ConanYang
  • ConanYang
  • 2011年11月08日 18:41
  • 1744
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:keil c51编译器的一些使用心得(一)
举报原因:
原因补充:

(最多只允许输入30个字)