通過*.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)