视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
ERROR L107 ADDRESS SPACE OVERFLOW
2025-10-02 15:37:29 责编:小OO
文档
ERROR L107: ADDRESS SPACE OVERFLOW

我用KEIL选用small模式编译一个程式时老时出错,信息如下。 

*** ERROR L107: ADDRESS SPACE OVERFLOW 

... ... 

Program Size: data=217.6 xdata=0 code=5314 

Target not created 

芯片我选的是ATC52,RAM有256呀,怎么会OVERFLOW呢? 

但是如果编译模式选用Compact或large时就一切正常。 

... ... 

Program Size: data=110.6 xdata=111 code=5914 

"test" - 0 Error(s), 22 Warning(s). 

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

排开Keil编译器有问题,可以肯定是你的内存空间溢出了 

Keil 中关于 107 错误的描述是这样的: 

========================================= 

Error L107 (ADDRESS SPACE OVERFLOW) 

Summary    *** Error L107 

     ADDRESS SPACE OVERFLOW 

     SPACE: space-name 

     SEGMENT: segment-name 

Description    The specified segment cannot be located at the specified address space. The segment is ignored.   

========================================= 

如果你仍要坚持自己的观点,只能去问 keil 公司的 

前面有些兄弟的说法有二点是不确切的: 

①就是超过变量128后必须使用compact模式编译 

     实际的情况是只要编译指示data=xxx 不超过 256.0 就可以用 small 编译 

②128以上的某些地址为特殊寄存器使用,不能给程序用 

     特殊寄存器虽然使用重复的地址,但是用不同的指令访问,并不会占用RAM空间 

但 small 模式下未指存储类型的变量默认为data型,即直接寻址,只能访问低 128 个字节,但这 128 个字节也不是全为你程序所有,寄存器 R0-R7必须映射到低RAM,要占去 8 个字节,如果使用寄存组切换,占用的更多。 

所以你可以使用 data 区最大为 120 字节,超出 120 个字节则必须用 idata 显示的指定为间接寻址,另外堆栈至少要占用一个字节,所以你最多能使用 127 上字节(如果) 

就是说极限情况下你可以定义的变量可占 247 个字节 

当然,实际应用中堆栈为一个字节肯定是不够用的,但如果嵌套调用层数不深,有十几个字节也够有了,所以你的 217.6 个字节的占用量应该是可以满足的 

为了验上面的观点,写了个例子 

#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; 

     } 

可以计算 R0-7(8) + tt1(120) + tt2(127) + SP(1) 总共 256 个字节 

keil 编译的结果如下: 

Program Size: data=256.0 xdata=0 code=30 

creating hex file from ".\\Debug\\Test"... 

".\\Debug\\Test" - 0 Error(s), 0 Warning(s). 

(我的测试环境为 XP + Keil C 7.5) 

这段程序已经达到了内存分配的极限,再定义任何全局变量或将数组加大,编译都会报错 107,也就是跟你碰到的一样的错误信息 

这里就要引出一个问题:为什么变量 i、j 不计算在内? 

这是因为 i、j 是局部变量,编译器会试着将其优化到寄存器 Rx 或栈。问题也就在这了,如果局部变量过多中定义了局部数组,编译器无法将其优化,就必须使用 RAM 空间,虽然全局变量的分配经过精心计算没有超出使用范围,仍会产生内存溢出的错误! 

而编译器是否能成功的优化变量是根据你的代码来的 

上面的代码中,循环是臃肿的,变量 j 是完全不必要,那么将代码改成 

UCHAR i; 

UCHAR j; 

for(i = 0; i < LEN; ++i )

     tt1[i] = 0x55; 

再编译看看,出错了吧! 

因为编译器不知道该如何使用 j,所以没能优化,j 须占 RAM 空间,RAM 就溢出了。(有些编译器会自动将这个无用的变量去掉,但这个不在讨论之列了) 

综上所述,我建议你重新审查你程序中的变量定义,或者将你的程序帖出来(不需要代码,只要变量定义部分,包括子程序) 

从你的两次编译提法来看,改为 compact 后有 111 个字节移到了 xdata,有个简单的方法就是打开你的输出文件夹中的 .M51 符号表文件,查找哪些变量被移到了 xdata,然后修改你的程序,在这些变量前加上 idata,再编译看看 

另外,对 idata 的定义的变量最好放在 data 变量之后 

对于这一种定义 

uchar c1; 

idata uchar c2; 

uchar c3; 

变量 c2 肯定会以间接寻址,但它有可以落在 data 区域,就浪费了一个可直接寻址的空间下载本文

显示全文
专题