原文地址:https://blog.csdn.net/liucheng5037/article/details/46934147 通過*.m51文件我們可以清楚的看到單片機存儲器的使用情況,以及可以看到每個變量包括局部變量的位置。
之前碰到一個問題,同樣的程序,在small模式下編譯後運行沒問題,但在large模式下可以編譯,但是運行出錯。最後查看m51文件,發現了問題,在一個對時序要求很嚴格的地方聲明幾個局部變量,這幾個局部變量有的被分配到data中,有的分配到xdata,在xdata中的變量訪問時間要大於data中,導致整個代碼時間管控出現混亂,最後將分配到xdata的變量用data修飾後,,編譯成功通過。
下面是對m51文件的解析,參考一下:
BL51 BANKED LINKER/LOCATER V6.11, INVOKED BY:
C:\KEIL\C51\BIN\BL51.EXE 1910base.obj, 1910.obj TO Keil_1910 RAMSIZE (256) STACK (?STACK (0080H))
MEMORY MODEL: SMALL WITH FLOATING POINT ARITHMETIC
INPUT MODULES INCLUDED:
1910base.obj (PROC1910)
1910.obj (1910)
C:\KEIL\C51\LIB\C51FPS.LIB (?C?FPADD)
……………………………… ;省略類同部分
C:\KEIL\C51\LIB\C51S.LIB (?C?LSTPDATA)
LINK MAP OF MODULE: Keil_1910 (PROC1910)
; 存儲器數據分配情況
; 類型 起始地址 長度 類型 段名
TYPE BASE LENGTH RELOCATION SEGMENT NAME
-----------------------------------------------------
* * * * * * * D A T A M E M O R Y * * * * * * * ; 內部數據內存區分配情況,REG代表是常規寄存器,
REG 0000H 0008H ABSOLUTE "REG BANK 0" ; 寄存器類型,從0000H開始,0008H個字節,絕對定位,寄存器BANK0
REG 0008H 0008H ABSOLUTE "REG BANK 1" ; 寄存器類型,從0000H開始,0008H個字節,絕對定位,寄存器BANK1
DATA 0010H 0006H UNIT ?DT?1910
BL51 BANKED LINKER/LOCATER V6.11 12/30/2009 16:15:01 PAGE 2
DATA 0016H 0005H UNIT ?DT?_WRITESLITPARAMETER?1910 ;DATA代表是DATA型數據,可訪問地址範圍0-128,或者在 128 .. 255 範圍內的一個特殊功能寄存器(SFR),以直接尋址方式操作
DATA 001BH 0004H UNIT ?DT?_READSLITPARAMETER?1910
001FH 0001H *** GAP *** ;代表空餘,未用
DATA 0020H 0001H BIT_ADDR ?BA?1910
BIT 0021H.0 0001H.4 UNIT ?BI?1910 ;BIT代表可以位操作的數據,是在內部數據存儲空間中 20H .. 2FH 區域中一個位的地址,或者 8051 位可尋址 SFR 的一個位地址。
BIT 0022H.4 0000H.4 UNIT _BIT_GROUP_
DATA 0023H 002DH UNIT _DATA_GROUP_
IDATA 0050H 001FH UNIT _IDATA_GROUP_ ;IDATA是可訪問地址範圍 0 to 255 內的數據,以間接尋址方式操作,速度略慢於DATA型數據
IDATA 006FH 0006H UNIT ?ID?1910
0075H 000BH *** GAP ***
IDATA 0080H 0001H UNIT ?STACK ;堆棧區,8051壓棧的方式是向上增長,可絕對定位
* * * * * * * X D A T A M E M O R Y * * * * * * * ;外部數據內存分配情況,XDATA表示數據存放在外部數據存儲器上
XDATA 0000H 0065H UNIT ?XD?1910 ;XDATA是存放在外部數據存儲器上的數據,可訪問地址範圍0-65535,速度最慢
XDATA 0065H 000CH UNIT _XDATA_GROUP_
* * * * * * * C O D E M E M O R Y * * * * * * * ;程序存儲器分配情況,CODE代表是的程序指令
CODE 0000H 0003H ABSOLUTE
CODE 0003H 0005H UNIT ?PR?RESETWATCHDOGTIMER?1910
0008H 0003H *** GAP ***
CODE 000BH 0003H ABSOLUTE
………………………… ;省略類同部分
CODE 000EH 0011H UNIT ?PR?_XWRITEPOINTER?1910
CODE 5846H 0039H UNIT ?PR?_READPORT?1910
CODE 587FH 0031H UNIT ?PR?_X5045_WRITE?1910
CODE 58B0H 0030H UNIT ?PR?X5045_READ?1910
CODE 58E0H 002CH UNIT ?PR?INITSYSTEM?1910
CODE 590CH 002CH UNIT ?PR?_XOUTBYTE?1910
CODE 5938H 0028H UNIT ?PR?XINBYTE?1910
CODE 5960H 0025H UNIT ?PR?_XREADCHAR?1910
CODE 5985H 0020H UNIT ?PR?READSERIALADDRESS?1910
CODE 59A5H 0020H UNIT ?CO?1910
CODE 59C5H 0017H UNIT ?PR?SETWRITESTATE?1910
CODE 59DCH 000CH UNIT ?PR?GETWIPSTATE?1910
CODE 59E8H 000CH UNIT ?PR?_ABS?ABS
OVERLAY MAP OF MODULE: Keil_1910 (PROC1910)
;以下是各函數中的數據分配情況
;段名 位操作數據起址地址 DATA數據 IDATA數據 XDATA數據
SEGMENT BIT_GROUP DATA_GROUP IDATA_GROUP XDATA_GROUP
+--> CALLED SEGMENT START LENGTH START LENGTH START LENGTH START LENGTH
----------------------------------------------------------------------------------------------------------------------
?C_C51STARTUP ----- ----- ----- ----- ----- ----- ----- -----
+--> ?PR?MAIN?1910
+--> ?C_INITSEG
; main()函數中數據使用情況(下面是調用的函數列表)
?PR?MAIN?1910 ----- ----- 0023H 0001H ----- ----- ----- -----
+--> ?PR?INITSYS?1910
+--> ?PR?SENDBACKACCUMULATEERROR?1910
+--> ?PR?INSTRECEIVEOK?1910
+--> ?PR?EXECUTEINSTRUCTION?1910
+--> ?PR?RESETWATCHDOGTIMER?1910
…………………………………;省略類同部分
;以下是變量、常量和寄存器等的存儲位置分配
SYMBOL TABLE OF MODULE: Keil_1910 (PROC1910)
;地址 類型 名稱
VALUE TYPE NAME
----------------------------------
------- MODULE PROC1910
C:55B0H SEGMENT ASMFUNCTIONS ;C:55B0H--C代表是在Code區,即存在程序存儲器(ROM)上,55B0H是地址
C:55C1H PUBLIC DETERMINEBAUDRATE
……………………………………;省略類同部分
D:00A8H SYMBOL IE ;D代表DATA型數據,存在RAM上0-127之間,或者在 128 .. 255 範圍內的一個特殊功能寄存器(SFR),
……………………………………;類同部分省略
N:0000H SYMBOL PROC1910
……………………………………;
B:0088H.4 SYMBOL TR0 ;B代表可以位尋址的數據或寄存器
B:0088H.6 SYMBOL TR1
……………………………………;
C:0000H SYMBOL _ICE_DUMMY_
X:0000H PUBLIC LampMotorCurrentPhase ;X代表存放在外部存儲器XRAM區的數據
C:4E55H PUBLIC SendBack
…………………………………;
C:0026H PUBLIC ExecuteInstruction ;C代表村放在CODE驅動的數據或指令
D:00B0H PUBLIC P3
C:4ADEH PUBLIC _ReadAD
C:568AH PUBLIC InstReceiveOK
……………………………………;
I:0071H PUBLIC ScanEndWaveLength ;I 代表可以IDATA型數據
…………………………………
C:41E9H PUBLIC _CheckLampEnergy
X:0049H PUBLIC FilterMotorCurrentPhase
……………………………………;省略
;以下是編譯結果
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?_WRITESLITPARAMETER?1910
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?ASSIGNSLITPARAMETER?1910
Program Size: data=117.0 xdata=113 code=23021
LINK/LOCATE RUN COMPLETE. 2 WARNING(S), 0 ERROR(S)