源于前幾天想擴充51單片機的外部ROM,網上能搜尋到的擴充方式都是将EA引腳接地,讓MCU上電後從外部ROM開始執行。但檢視晶片手冊,明明說EA為高時,程式從片内ROM執行,當執行到0x1000時(标準51單片機),會跳轉到片外ROM執行。按網上的做法,為了擴充個片外ROM,片内的基本ROM都不用了,有點浪費了,于是開始找資料如何從片内跳轉到片外,期間學習到intel hex檔案格式,是以在此記錄一下備忘。
接下來是我的整理:
keil c建立的工程,經過編譯連接配接生成一個hex檔案,看名字總覺得是個16進制檔案,憑感覺這個檔案裡至少包含指令啥的吧,那就用16進制文本編輯器打開看看是什麼:
假設源碼是這樣的:
ORG 1000H
STAR:
MOV A,#0AAH
MOV P1,A
MOV A,#55H
MOV P1,A
SJMP STAR
END
經過編譯後生成hex,參考了intel彙編指令的編碼,mov a,#0aah應該被編譯成74AA,檢視一下hex中有沒有這段内容

16進制部分,完全沒找到74AA這段内容,再看下MOV A,#55H對應的代碼7455,也沒找到!我擦,不能吧,沒這些内容,mcu怎麼執行?難道懷疑intel指令不對?人家大業大我們哪有資格懷疑,還是從自身檢查起吧。
第一個連接配接的結尾部分(這麼重要的内容作者你居然放最後,夠了!)提到:
"hex檔案是用ASCII來表示二進制的數值,例如一個8bit的二進制數值0x3F,用ASCII來表示就需要分别表示為字元‘3’和字元‘F’,每個字元需要一個Byte,是以hex檔案需要2倍的空間"
意思是,hex檔案本身存放的内容全是可見字元ASCII,這些ascii碼中的0-9,A-F對應了16進制中的各個數字;一個位元組包含兩個16進制數,是以,需要hex檔案中的兩個位元組的ascii碼表示一個位元組機器碼。
回到上圖,來到偏移0x11-0x14處,37 34 35 35這四個ascii碼對應的字元是7455,好像就是MOV A,#55H的編碼,再到偏移0x9-0x0c處37 34 41 41這四個ascii碼對應了74AA,正好是mov a,#0AAH。好吧,好像有這麼回事了,再試試其他指令,P1口的位址是90H,偏移0x0d-0x11之間的46 35 39 30對應F590 正好是MOV P1,A的編碼。終于能解釋的通去哪找指令了----用winhex最右邊的可見字元部分檢視指令編碼。