加载中…
正文 字体大小:

Keil   中关于   107   错误的描述

(2007-08-29 09:16:46)
分类: C语言学习
 

排开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,要占去    个字节,如果使用寄存组切换,占用的更多。  
   
  所以你可以使用   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;       LEN;   ++i   
          
                    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"     Error(s),    Warning(s).  
  (我的测试环境为   XP    Keil    7.5)  
   
  这段程序已经达到了内存分配的极限,再定义任何全局变量或将数组加大,编译都会报错   107,也就是跟你碰到的一样的错误信息  
   
  这里就要引出一个问题:为什么变量   i、j   不计算在内?  
  这是因为   i、j   是局部变量,编译器会试着将其优化到寄存器   Rx   或栈。问题也就在这了,如果局部变量过多中定义了局部数组,编译器无法将其优化,就必须使用   RAM   空间,虽然全局变量的分配经过精心计算没有超出使用范围,仍会产生内存溢出的错误!  
   
  而编译器是否能成功的优化变量是根据你的代码来的  
  上面的代码中,循环是臃肿的,变量    是完全不必要,那么将代码改成  
   
  UCHAR   i;  
  UCHAR   j;  
   
  for(i    0;       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   区域,就浪费了一个可直接寻址的空间   
  

0

阅读 评论 收藏 转载 喜欢 打印举报
  • 评论加载中,请稍候...
发评论

       

    验证码: 请点击后输入验证码 收听验证码

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有