C51的内存分配不同于一般的PC,内存空间有限,选用掩盖和同享技能。在Keil编译器中,通过编译后,会构成一个M51文件,在其内部能够具体的看到内存的分配状况。
C51内存常见的两个误区:
(1)
其实,只要不超越256字节,都能够用SMALL形式
(2)
其实,因为C51寻址的不同,高128字节也能够用来存储变量,虽与SFR地址相同,但寻址的方法不同。
下面通过几个程序来看内存的分配。
*******************************************************************************
//程序1:
#include
void main()
{}
Program Size: data=9.0 xdata=0 code=16
TYPE
*******************************************************************************
从上面能够看到,即便程序内部无任何变量和函数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
*******************************************************************************
存在全局变量时,依据全局变量的类型分配相应的存储空间。
看下面的程序
*****************************************************************
//程序3:
#include
#define uint unsigned int
#define uchar unsigned char
uchar a;
uint b;
uint sum(uint c)
{
}
void main()
{}
Program Size: data=12.0 xdata=0 code=17
TYPE
********************************************************************
与上面的程序想比较,发现内存并没有任何的改变。
看下面的程序
***************************************************************************
//程序4:
#include
#define uint unsigned int
#define uchar unsigned char
uchar a;
uint b;
uint sum(uint c)
{
}
void main()
{
}
Program Size: data=12.0 xdata=0 code=28
TYPE
****************************************************************************
这与上面的内存运用相同,在这个程序中通过反汇编,检查编译后的汇编程序能够发现,参数的传递通过通用寄存器完结,没有占用新的内存。编译器将其优 化的通用寄存器(寄存器一般传递3个参数,超越3个参数时,剩余的参数通过分配空间地址的方法来访问。可是分配的内存空间包含了寄存器传递的3个参数在内 的一切参数的空间。详见《Parameter And Local Variable 》和《Parameter and Register》)和栈中(程序7),可是假如参数或局部变量过多,则状况就彻底不同(程序6)。
再看下面的程序
*******************************************************************
//程序5
#include
#define uint unsigned int
#define uchar unsigned char
uchar a;
uint b;
uint sum(uint c)
{
}
void main()
{
}
Program Size: data=16.0 xdata=0 code=21
TYPE
******************************************************************
相同的程序,内部RAM的运用状况又发生了改变。函数未被调用,且参数与局部变量都没有运用。
源文件通过编译后构成obj文件,各个obj文件便是一个模块,每个模块中都含有代码段和数据段,也便是,代码在ROM占有多少CODE空间,数据在RAM里占用多少空间等信息。