新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Keil的ERROR L107:ADDRESS SPACE OVERFLOW問題

        Keil的ERROR L107:ADDRESS SPACE OVERFLOW問題

        作者: 時間:2016-11-24 來源:網絡 收藏
        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編譯器有問題,可以肯定是你的內存空間溢出了
        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 ".DebugTest"...
        ".DebugTest" - 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 區域,就浪費了一個可直接尋址的空間


        關鍵詞: KeilERRORL10

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 江油市| 文昌市| 句容市| 金寨县| 孟州市| 哈尔滨市| 祁东县| 即墨市| 甘肃省| 东港市| 仪征市| 洛宁县| 绵竹市| 彝良县| 上思县| 方城县| 永春县| 元阳县| 鹰潭市| 山西省| 松桃| 成武县| 淳安县| 甘德县| 罗定市| 开原市| 会泽县| 芮城县| 邻水| 昌吉市| 富阳市| 鹿邑县| 灵山县| 类乌齐县| 邯郸县| 航空| 太仆寺旗| 泸西县| 平果县| 渝北区| 东兴市|