新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Keil C51内存分配与优化

Keil C51内存分配与优化

作者: 时间:2016-11-28 来源:网络 收藏

obj(lib)文件然后经过l51.exe(bl51.exe),就是说把可执行代码模块根据连接定位参数地址上连接在一起();数据段也连接在 一起,在ram空间中分配.对ram空间的分配中就有一个连接过程"覆盖分析".调用一个c函数,就会为这个函数所使用的ram空间进行分配(一些局部变 量),这个函数返回时再回收分配给他的ram空间,根据函数互相之间的调用前后关系,编译器就可以时实的知道ram空间的使用情况(其中就存在一个函数重 入的问题),作为连接时ram空间分配的参数. 如果源文件中的函数(模块)从来没有被任何函数显示的调用(所谓非显示调用就是这段代码,连接器目前还不知道这段代码什么时候会被调用或是否会被调用), 连接时就会为它分配永远有效的ram空间(就象全局变量),不会被回收。

(http://blog.sina.com.cn/s/blog_74ee88b80100pqed.html)

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

//程序6

#include

#define uint unsigned int

#define uchar unsigned char

uchar a;

uint b;

uint sum2(uint e,uint f,uint g,uint j)

{

uint i;

i = e+f+g+j;

return i;

}

void main()

{

b = sum2(1,2,3,4);

}

Program Size: data=20.0 xdata=0 code=58

TYPEBASELENGTHRELOCATIONSEGMENT NAME

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

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

REG0000H0008HABSOLUTE"REG BANK 0"

DATA0008H0008HUNIT_DATA_GROUP_

DATA0010H0003HUNIT?DT?MAIN

IDATA0013H0001HUNIT?STACK

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

在上面的程序中如果将sum2中的j去掉,那么data = 12.0。

通过程序5和6可以看到,两个程序的M51文件中的蓝色部分的segement name的名称有很大的区别。_DATA_GROUP_是一个OVERALY GROUPS(覆盖组)。它是链接器产生的可覆盖的一个数据段。而上面的程序5中的?DT?_SUM?MAIN,则是一个函数段。

在Keil中对OVERALY GROUPS的解释为:

When performing overlay analysis, the linker creates groups of segments that are overlaid. The group name indicates the memory type of the variables that it includes.

Group Name

Segment
Prefix

Memory
Model

Description

_BIT_GROUP_

?BI?

All

Variables and arguments of typebit.

_DATA_GROUP_

?DT?

SMALL

Variables and arguments other thanbit.

_PDATA_GROUP_

?PD?

COMPACT

Variables and arguments other thanbit.

_XDATA_GROUP_

?XD?

LARGE

Variables and arguments other thanbit.

When the linker overlays function data memory and creates a group, that groups appears in the linker map files memory map section.

STARTSTOPLENGTHALIGNRELOCMEMORY CLASSSEGMENT NAME
======================================================================
* * * * * * * * * * *D A T AM E M O R Y* * * * * * * * * * * * *
000000H000007H000008H---AT..DATA"REG BANK 0"
000008H00001AH000013HBYTEUNITDATA_DATA_GROUP_
00001BH00001BH000001HBYTEUNITIDATA?STACK

Groups are created based on the memory model of the function (which specifies the memory class where parameters and variables are stored) and on any variables defined with a specific memory space.

在keil生成的M51函数中有OVERLAY MAP OF MODULE,对程序中函数调用的覆盖有详细的说明。

//程序7

#define LEN 120
data uchar tt1[LEN];
idata uchar tt2[127];

void main()
{
uchar i,j;

for(i = 0;i < LEN; ++i )
{
j = i;
tt1[j] = 0x55;
}
}

变量i和j通过编译器的优化占用了通用寄存器,R0-8[8]+tt1[120]+tt2[127]+SP[1]共256字节;

而如果将程序7中j=i删掉。上面声明了uchar j,但是下面没有应用,因此编译器不知道该如何处理j,就让其占用了一个RAM空间不再存在通用寄存器中,出现了内存溢出。(有的编译器会将不用的变量自动删除)

局部变量占用通用寄存器,变量在声明时就被分配了空间;局部变量只有在被声明、赋值且被使用后才认为是局部变量被放置在通用寄存器中,否则被认为是全局变量;在循环中,R7中放置循环数。(自加)

由于data区的存取速度快,变量尽量的放在该区,但是由于idata可以访问整个256字节的RAM,如果data区变量较少,idata型的变量也会占有data区,减少了可直接访问的存储空间,因此在变量定义的时候尽量将idata型的变量定义在data型变量后。

uchar c1;
idata uchar c2;
uchar c3;
变量 c2 肯定会以间接寻址,但它有可能落在 data 区域,就浪费了一个可直接寻址的空间

变量的优化

(http://weimenlove.blog.163.com/blog/static/177754732009418105322546/)

(1)将访问频率高的变量放在data区

(2)提高内存的复用率。尽可能的利用局部变量,由于局部变量的存取速度快。在程序7中可以看到,i和j没有占用内存,子程序中使用内存数量不大的变量尽量定义为局部变量。

(3)对于指针数组的定义,尽量指明存储类型。尽量使用无符号类型变量。8051不支持有符号数计算,需要通过其他的库来处理,大大降低了运行的速度,增加了内存的利用。

(4)避免出现内存空洞。在M51中可以很清楚的看到内存的分配情况,如果全局变量和局部变量的分配不合理,有时会出现下面的情况:

0010H0012H*** GAP ***

表示从0010开始有0012H个字节未利用。造成这种情况的原因是局变量太多、多个子程序中的局部变量数目差异太大、使用了寄存器切换但未充分利用

(5)避免出现未使用的变量或者函数。


上一页 1 2 下一页

关键词: KeilC51内存分

评论


技术专区

关闭