<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Keil的ERROR L107:ADDRESS SPACE OVERFLOW問題

          Keil的ERROR L107:ADDRESS SPACE OVERFLOW問題

          作者: 時間:2016-11-24 來源:網(wǎng)絡(luò) 收藏
          ERROR L107: ADDRESS SPACE OVERFLOW問題原因分析及解決
          用KEIL選用small模式編譯一個程式時老時出錯,信息如下。
          *** ERROR L107: ADDRESS SPACE OVERFLOW
          ... ...
          Program Size: data=217.6 xdata=0 code=5314
          Target not created
          芯片我選的是AT89C52,RAM有256呀,怎么會OVERFLOW呢?
          但是如果編譯模式選用Compact或large時就一切正常。
          ... ...
          Program Size: data=110.6 xdata=111 code=5914
          "test" - 0 Error(s), 22 Warning(s).
          請大俠們指教!
          ---------------------------------------------------------------
          排開Keil編譯器有問題,可以肯定是你的內(nèi)存空間溢出了
          Keil 中關(guān)于 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.
          =========================================
          如果你仍要堅(jiān)持自己的觀點(diǎn),只能去問 keil 公司的
          前面有些兄弟的說法有二點(diǎn)是不確切的:
          ①就是超過變量128后必須使用compact模式編譯
          實(shí)際的情況是只要編譯指示data=xxx 不超過 256.0 就可以用 small 編譯
          ②128以上的某些地址為特殊寄存器使用,不能給程序用
          特殊寄存器雖然使用重復(fù)的地址,但是用不同的指令訪問,并不會占用RAM空間
          但 small 模式下未指存儲類型的變量默認(rèn)為data型,即直接尋址,只能訪問低 128 個字節(jié),但這 128 個字節(jié)也不是全為你程序所有,寄存器 R0-R7必須映射到低RAM,要占去 8 個字節(jié),如果使用寄存組切換,占用的更多。
          所以你可以使用 data 區(qū)最大為 120 字節(jié),超出 120 個字節(jié)則必須用 idata 顯示的指定為間接尋址,另外堆棧至少要占用一個字節(jié),所以你最多能使用 127 上字節(jié)(如果)
          就是說極限情況下你可以定義的變量可占 247 個字節(jié)
          當(dāng)然,實(shí)際應(yīng)用中堆棧為一個字節(jié)肯定是不夠用的,但如果嵌套調(diào)用層數(shù)不深,有十幾個字節(jié)也夠有了,所以你的 217.6 個字節(jié)的占用量應(yīng)該是可以滿足的
          為了驗(yàn)上面的觀點(diǎn),寫了個例子
          #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;
          }
          }
          可以計(jì)算 R0-7(8) + tt1(120) + tt2(127) + SP(1) 總共 256 個字節(jié)
          keil 編譯的結(jié)果如下:
          Program Size: data=256.0 xdata=0 code=30
          creating hex file from ".DebugTest"...
          ".DebugTest" - 0 Error(s), 0 Warning(s).
          (我的測試環(huán)境為 XP + Keil C 7.5)
          這段程序已經(jīng)達(dá)到了內(nèi)存分配的極限,再定義任何全局變量或?qū)?shù)組加大,編譯都會報錯 107,也就是跟你碰到的一樣的錯誤信息
          這里就要引出一個問題:為什么變量 i、j 不計(jì)算在內(nèi)?
          這是因?yàn)?i、j 是局部變量,編譯器會試著將其優(yōu)化到寄存器 Rx 或棧。問題也就在這了,如果局部變量過多中定義了局部數(shù)組,編譯器無法將其優(yōu)化,就必須使用 RAM 空間,雖然全局變量的分配經(jīng)過精心計(jì)算沒有超出使用范圍,仍會產(chǎn)生內(nèi)存溢出的錯誤!
          而編譯器是否能成功的優(yōu)化變量是根據(jù)你的代碼來的
          上面的代碼中,循環(huán)是臃腫的,變量 j 是完全不必要,那么將代碼改成
          UCHAR i;
          UCHAR j;
          for(i = 0; i < LEN; ++i )
          {
          tt1[i] = 0x55;
          }
          再編譯看看,出錯了吧!
          因?yàn)榫幾g器不知道該如何使用 j,所以沒能優(yōu)化,j 須占 RAM 空間,RAM 就溢出了。(有些編譯器會自動將這個無用的變量去掉,但這個不在討論之列了)
          綜上所述,我建議你重新審查你程序中的變量定義,或者將你的程序帖出來(不需要代碼,只要變量定義部分,包括子程序)
          從你的兩次編譯提法來看,改為 compact 后有 111 個字節(jié)移到了 xdata,有個簡單的方法就是打開你的輸出文件夾中的 .M51 符號表文件,查找哪些變量被移到了 xdata,然后修改你的程序,在這些變量前加上 idata,再編譯看看
          另外,對 idata 的定義的變量最好放在 data 變量之后
          對于這一種定義
          uchar c1;
          idata uchar c2;
          uchar c3;
          變量 c2 肯定會以間接尋址,但它有可以落在 data 區(qū)域,就浪費(fèi)了一個可直接尋址的空間


          關(guān)鍵詞: KeilERRORL10

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();