微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Keil C51内存分配与优化

Keil C51内存分配与优化

时间:11-28 来源:互联网 点击:
C51的内存分配不同于一般的PC,内存空间有限,采用覆盖和共享技术。在Keil编译器中,经过编译后,会形成一个M51文件,在其内部可以详细的看到内存的分配情况。

C51内存常见的两个误区:

(1)变量超过128字节后必须用COMPACT模式。

其实,只要不超过256字节,都可以用SMALL模式

(2)内部RAM,128字节以上的是SFR用,不给程序用。

其实,由于C51寻址的不同,高128字节也可以用来存储变量,虽与SFR地址相同,但寻址的方式不同。

下面通过几个程序来看内存的分配。

*******************************************************************************

//程序1:

#include

void main()

{}

Program Size: data=9.0 xdata=0 code=16

TYPEBASELENGTHRELOCATIONSEGMENT NAME

-----------------------------------------------------

* * * * * * *D A T AM E M O R Y* * * * * * *

REG0000H0008HABSOLUTE"REG BANK 0"

IDATA0008H0001HUNIT?STACK

*******************************************************************************

从上面可以看到,即使程序内部无任何变量和函数data也会为9.0。这9个字节内存分别为R0-R8和一个堆栈指针(C51的堆栈是“grow up”,即使堆栈中没有内容,也会有一个栈底指针)。data区中由于R0-R8占有8个存储空间,因此data区最大为120字节(栈在所有的变量空间 之后),如果超过120个字节则由idata显式的指定为间接寻址。对于整个内部256字节的RAM,在极端的情况下,最大的变量为247字节。

当定义全局变量时

*******************************************************************************

//程序2:

#include

#define uint unsigned int

#define uchar unsigned char

uchar a;

uint b;

void main()

{}

Program Size: data=12.0 xdata=0 code=16

TYPEBASELENGTHRELOCATIONSEGMENT NAME

-----------------------------------------------------

* * * * * * *D A T AM E M O R Y* * * * * * *

REG0000H0008HABSOLUTE"REG BANK 0"

DATA0008H0003HUNIT?DT?MAIN

IDATA000BH0001HUNIT?STACK

* * * * * * *C O D EM E M O R Y* * * * * * *

CODE0000H0003HABSOLUTE

CODE0003H000CHUNIT?C_C51STARTUP

CODE000FH0001HUNIT?PR?MAIN?MAIN

*******************************************************************************

存在全局变量时,根据全局变量的类型分配相应的存储空间。

看下面的程序

*****************************************************************

//程序3:

#include

#define uint unsigned int

#define uchar unsigned char

uchar a;

uint b;

uint sum(uint c)

{

uint d;

d = c;

return d;

}

void main()

{}

Program Size: data=12.0 xdata=0 code=17

TYPEBASELENGTHRELOCATIONSEGMENT NAME

-----------------------------------------------------

* * * * * * *D A T AM E M O R Y* * * * * * *

REG0000H0008HABSOLUTE"REG BANK 0"

DATA0008H0003HUNIT?DT?MAIN

IDATA000BH0001HUNIT?STACK

* * * * * * *C O D EM E M O R Y* * * * * * *

CODE0000H0003HABSOLUTE

CODE0003H000CHUNIT?C_C51STARTUP

CODE000FH000CHUNIT?PR?MAIN?MAIN

CODE001BH0001HUNIT?PR?_SUM?MAIN

********************************************************************

与上面的程序想比较,发现内存并没有任何的变化。

看下面的程序

***************************************************************************

//程序4:

#include

#define uint unsigned int

#define uchar unsigned char

uchar a;

uint b;

uint sum(uint c)

{

uint d;

d = c;

return d;

}

void main()

{

b = sum(5);

}

Program Size: data=12.0 xdata=0 code=28

TYPEBASELENGTHRELOCATIONSEGMENT NAME

-----------------------------------------------------

* * * * * * *D A T AM E M O R Y* * * * * * *

REG0000H0008HABSOLUTE"REG BANK 0"

DATA0008H0003HUNIT?DT?MAIN

IDATA000BH0001HUNIT?STACK

* * * * * * *C O D EM E M O R Y* * * * * * *

CODE0000H0003HABSOLUTE

CODE0003H000CHUNIT?C_C51STARTUP

CODE000FH000CHUNIT?PR?MAIN?MAIN

CODE001BH0001HUNIT?PR?_SUM?MAIN

****************************************************************************

这与上面的内存使用相同,在这个程序中通过反汇编,查看编译后的汇编程序可以发现,参数的传递通过通用寄存器完成,没有占用新的内存。编译器将其优 化的通用寄存器(寄存器一般传递3个参数,超过3个参数时,多余的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top