您现在的位置: 主页 > MCU > 单片机应用 > keil c51编译器的一些使用心得 -
本文所属标签:
为本文创立个标签吧:

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

来源: 网络用户发布,如有版权联系网管删除 2018-09-09 

[导读]现在的存储器已经不像七八年前那样昂贵了,但是ram相对于rom和eeprom的价格还是不可同样看待的,所以程序中节省内存在现在看来还是非常关键的。原因有以下几点:1.ram的存取速度相对于eeprom的存取速度要快很多倍,不

现在的存储器已经不像七八年前那样昂贵了,但是ram相对于rom和eeprom的价格还是不可同样看待的,所以程序中节省内存在现在看来还是非常关键的。原因有以下几点:

本文引用地址: http://www.21ic.com/app/mcu/201809/784966.htm

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。

所以,建议大家如果暂时不调用的函数最好屏蔽掉,以免影响整体的内存分配。




              查看评论 回复



嵌入式交流网主页 > MCU > 单片机应用 > keil c51编译器的一些使用心得 -
 

"keil c51编译器的一些使用心得 -"的相关文章

网站地图

围观()