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)避免出现未使用的变量或者函数。
|