看到这篇C51的内存分配和优化的文章,个人觉得分析的十分到位,在这里转给大家
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
TYPE BASE LENGTH RELOCATION SEGMENT NAME
-----------------------------------------------------
* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
IDATA 0008H 0001H UNIT ?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
TYPE BASE LENGTH RELOCATION SEGMENT NAME
-----------------------------------------------------
* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA 0008H 0003H UNIT ?DT?MAIN
IDATA 000BH 0001H UNIT ?STACK
* * * * * * * C O D E M E M O R Y * * * * * * *
CODE 0000H 0003H ABSOLUTE
CODE 0003H 000CH UNIT ?C_C51STARTUP
CODE 000FH 0001H UNIT ?PR?MAIN?MAI