§4.7 匯編程序(MASM)
本節(jié)概述:
匯編程序的作用:
匯編語言源程序文件(ASM)->目標程序文件(OBJ)。
輸入:ASM文件。
輸出:OBJ文件 + 輸出列表文件(LST)+ 交叉引用文件(CRF)。
當源程序無語法錯誤時,生成OBJ文件。
可選擇是否生成LST和CRF文件。
教學目標
掌握或了解匯編的過程,掌握MASM的用法,了解相關(guān)的問題。
學習內(nèi)容:
MASM的用法
匯編過程
相關(guān)問題
重點難點
匯編過程。
學習方法
掌握或了解匯編的過程,掌握MASM的用法,了解相關(guān)的問題。
關(guān)鍵字
匯編過程
參考資料
1、《微型計算機技術(shù)及應用》,戴梅萼等編著,第二版,清華大學出版社
2、《微型計算機原理》,季維法等編著,第一版,電子科技大學出版社
3、《微型計算機原理—常見題型解析及模擬題》,武自芳主編,西北工業(yè)大學出版社
4、《80X86/80X87匯編語言程序設(shè)計》,洪志全等編著,電子科技大學出版社
§4.7.1 MASM的用法
以匯編TEST.ASM文件為例。
用法一:
H:\961234>masm↙
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
Source filename [.ASM]: test↙ ;輸入源程序文件名(擴展名可省略)
Object filename [test.OBJ]: ↙;缺省目標文件名為TEST.OBJ
Source listing [NUL.LST]: ↙;不生成LST文件,直接回車
Cross-reference [NUL.CRF]: ↙;不生成CRF文件,直接回車
51470 + 435154 Bytes symbol space free
0 Warning Errors ; 0個警告錯誤
0 Severe Errors ;0個嚴重錯誤
如果匯編程序能夠翻譯源程序,報告"0個警告錯誤"、"0個嚴重錯誤",同時,生成目標文件TEST.OBJ。
用法二:
H:\961234>masm test; //后接分后
輸入為test.asm,輸出為test.obj,不生成LST和CRF文件。
用法三:
H:\961234>masm test,,,, //后接四個逗號
輸入為test.asm,輸出為test.obj,test.lst,test.crf。
1、 目標文件OBJ
匯編程序MASM把源程序中的指令翻譯為機器碼,存入OBJ文件中。如果源程序中有語法錯誤,則不能生成OBJ文件。應修改語法錯誤,重新匯編,直到?jīng)]有任何語法錯誤、生成OBJ文件為止。
2、 列表文件LST
該文件列出指令及其對應的機器碼。如果源程序中有語法錯誤,錯誤信息也寫入LST文件中。
3、 交叉引用文件CRF
該文件中包含標識符(段名、過程名、變量名、標號)在源程序中定義的位置和被引用的位置。
CRF是二進制文件,可以使用實用程序CREF.EXE將其轉(zhuǎn)換為文本文件REF。
H:\961234>CREF test; //后接分號
§4.7.2 匯編過程
匯編程序MASM使用"機器指令表"和"偽指令表",把源程序文件ASM翻譯為目標文件OBJ。
1、 機器指令表
機器指令表是一張固定的表格,給出所有助記符指令與機器指令的對應關(guān)系。
如: MOV DS,AX → 8E,D8
MOV AX,4C00H→B8,00,4C
INT 21H→CD 21
2、 偽指令表
偽指令表給出全部偽指令。
3、 兩遍掃描
匯編程序MASM對源程序文件ASM執(zhí)行兩遍掃描,根據(jù)"機器指令表"和"偽指令表"把ASM文件翻譯為OBJ文件。
第一遍掃描:
任務:
(1) 語法檢查。
(2) 確定每一行源程序的段內(nèi)偏移地址,并記錄員程序定義的符號的偏移地址,形成一張"符號表"。
進行語法檢查時,首先讀入一個源程序語句,查找"偽指令表",檢查該語句是不是偽指令,如是偽指令,執(zhí)行該偽指令規(guī)定的操作。若該語句不是偽指令,查找"機器指令表",檢查該語句是不是機器指令。若讀入的語句既不是偽指令、也不是機器指令,表明源程序出現(xiàn)了語法錯誤,在屏幕上顯示出錯位置及錯誤原因,同時把錯誤信息寫入LST文件(如果要生成LST文件)。
匯編程序MASM使用"地址計數(shù)器"來確定每一行源程序的段內(nèi)偏移地址。開始匯編時,或在每一個"段"(SEGMENT)開始時,地址計數(shù)器的值初始化為0。每處理一條指令,地址計數(shù)器的值就增加一個值,該值等于該指令對應的機器指令的長度。
如果所處理的語句是偽指令DB、DW、DD、DT,則地址計數(shù)器增加的值等于這些偽指令定義的存儲區(qū)長度。
如果所處理的語句定義了符號,則把該符號名、屬性(過程的屬性有FAR、NEAR,變量的屬性有Byte、Word、DWord)、對應的地址計數(shù)值寫入"符號表"。
第一遍掃描(PASS1)的主要流程如圖1:

第二遍掃描:
第二遍掃描時,根據(jù)"符號表"、"機器指令表"、"偽指令表",把匯編語言指令翻譯為機器指令,完成匯編任務,生成OBJ、LST、CRF文件。
第二遍掃描的流程:

在第二遍掃描時,如有"表達式",如:
MOV AX,3*2
DB 4+5 則MASM將計算表達式的值。
§4.7.3 相關(guān)問題
1、 前向引用(提前引用、向前引用)
在匯編語句的操作數(shù)字段中,若出現(xiàn)變量或符號,有兩種情況:如果該變量或符號已經(jīng)定義過,稱為"后向引用"; 如果該變量或符號尚未定義,稱為"前向引用"。
匯編程序MASM在翻譯"JMP NEXT"指令時,若NEXT已定義,MASM已知NEXT與JMP的距離,可以正確計算"JMP NEXT"指令的長度,產(chǎn)生正確的機器指令。
匯編程序MASM在翻譯"JMP NEXT"指令時,若NEXT未定義(前向引用),MASM不知道NEXT與JMP的距離,此時,MASM假定它們在同一段,且假定其距離大于-128~+127,即產(chǎn)生機器碼:
EA XXXX
偏移量
MASM的假定有時不符合程序的實際情況,則產(chǎn)生錯誤的機器碼,為了避免這種情況,在編寫程序時,如果有前向引用,應指明引用的屬性(距離)。
如:
JMP SHORT NEXT ;(無PTR)
JMP NEAR PTR NEXT
JMP FAR PTR NEXT
注意:
(1) "JMP NEXT"與"JMP NEAR PTR NEXT"相同。
(2) 一般不區(qū)分"JMP SHORT NEXT"與"JMP NEAR PTR NEXT",因為把"JMP SHORT NEXT"處理為"JMP NEAR PTR NEXT"只是增加了機器指令的長度,不會使執(zhí)行結(jié)果出現(xiàn)錯誤。因此,程序中只區(qū)分"段間轉(zhuǎn)移"和"段內(nèi)轉(zhuǎn)移"。即, 出現(xiàn)段間轉(zhuǎn)移時,使用"JMP FAR PTR NEXT",否則,使用"JMP NEXT"。
(3)對于CALL指令,有類似概念。
段間調(diào)用: CALL FAR PTR SUBP
段內(nèi)調(diào)用:CALL SUBP
(4)對于條件轉(zhuǎn)移(JZ、JC、JP等)和循環(huán)控制指令(LOOP、LOOPZ、LOOPNE等),轉(zhuǎn)移的距離只能在-128~+127之間,不需要SHORT、NEAR PTR修飾,不允許出現(xiàn)FAR PTR。
(5)一般,把數(shù)據(jù)段放在代碼段之前,避免出現(xiàn)前向引用。

2、 浮動地址的概念
在匯編過程中,每個源程序段開始時,均把"地址計數(shù)器"清0,其后本段內(nèi)所有地址均為相對于起始地址的偏移量,把這些段組合成一個可執(zhí)行文件EXE(由連接程序LINK.EXE組合)時,除EXE中第一個段外,每個段的起始地址均要在0的基礎(chǔ)上"浮動"一個值,即,把所有地址變?yōu)橄鄬τ诘谝粋€段起始地址(其值為0)的偏移量。因此,匯編程序翻譯后,各符號的地址稱為"浮動地址"。在LST文件中,浮動地址以R標記(Relocation),如圖4-14所示。
(1) "MOV AX, DATA"。由于DATA是段地址,MASM把其起始地址設(shè)為0,LINK把DATA、CODE段組合成EXE文件時,DATA的值需重新定位,故DATA是浮動地址,LST 文件中,把"MOV AX, DATA" 的機器碼標記為"B8 __R"。
(2) "MOV CX, count"。MASM已知count的地址為006F,該指令被翻譯為"8B 0E 006F",但count的地址仍是浮動地址,也以R標記。
§4.8 連接程序(LINK)
本節(jié)概述:
匯編得到的OBJ文件是源程序?qū)臋C器碼,但該文件不能直接運行,因為OBJ文件中,各段是獨立的,它們的起始地址均被設(shè)為0,各段沒有形成一個整體。連接程序LINK把OBJ文件中的各段連接成一個整體:EXE文件。
教學目標
掌握連接的基本用法和它的功能及其過程。
學習內(nèi)容:
基本用法
功能
連接過程
重點難點
連接的基本用法和它的功能及其過程。
學習方法
掌握連接的基本用法和它的功能及其過程。
關(guān)鍵字
連接
參考資料
1、《微型計算機技術(shù)及應用》,戴梅萼等編著,第二版,清華大學出版社
2、《微型計算機原理》,季維法等編著,第一版,電子科技大學出版社
3、《微型計算機原理—常見題型解析及模擬題》,武自芳主編,西北工業(yè)大學出版社
4、《80X86/80X87匯編語言程序設(shè)計》,洪志全等編著,電子科技大學出版社
§4.8.1 基本用法
連接程序LINK把OBJ文件(一個或多個OBJ文件)中的各段連接成一個整體:EXE文件,其輸入是OBJ文件和LIB文件(庫文件,一種特殊的OBJ文件),輸出是EXE文件,也可以輸出映像文件MAP。
是否輸出MAP文件是可選的。
僅連接過程無錯誤時才能生成EXE文件,否則,不能生成EXE文件。
用法1:
H:961234>link↙
Microsoft (R) Overlay Linker Version 3.60
Copyright (C) Microsoft Corp 1983-1987. All rights reserved.
Object Modules [.OBJ]: test↙ 輸入目標文件名(擴展名可省略)
Run File [TEST.EXE]: ↙ 缺省可執(zhí)行文件名為TEST.EXE
List File [NUL.MAP]: ↙ 不生成MAP文件
Libraries [.LIB]: ↙ 無庫文件輸入
用法2:
H:961234>link test,,,,↙ 后接四個逗號
不出現(xiàn)上述提示,輸入test.obj,生成可執(zhí)行文件test.exe和映像文件test.map,無庫文件輸入。
用法3:
H:961234>link test;↙ 后接分號 不出現(xiàn)上述提示,輸入test.obj,生成可執(zhí)行文件test.exe,不產(chǎn)生映像文件test.map,無庫文件輸入。
§4.8.2 功能
1、 功能
總體上說,連接程序LINK的功能是把OBJ文件(一個或多個OBJ文件)中的各段連接成一個整體:EXE文件。具體功能為:
(1)為所有段分配存儲空間,確定各段相對于第一個段的起始地址的地址偏移量。
匯編程序MASM把各段的起始地址均設(shè)為0,把這些段連接為一個整體EXE文件時,需確定各段相對于第一個段的起始地址的地址偏移量。如確定"MOV AX,DATA"指令中DATA代表的值。
(2)確定匯編程序MASM不能確定的偏移地址,包括:
?、?浮動地址,如count的地址。
?、?外部符號的地址。
2、外部符號
在模塊化程序設(shè)計中,可以把一個大型程序的源程序存放為幾個源程序文件,每個文件稱為一個源程序"模塊"。每個源程序模塊被匯編程序MASM翻譯為獨立的OBJ文件(OBJ模塊),連接程序LINK把這些OBJ模塊連接為一個EXE文件。
在某個源程序模塊中,可以引用另一個源程序模塊中定義的符號(標號、過程名、變量)。這些符號不在本源程序模塊中定義,而在另一個源程序模塊中定義,稱為"外部符號"。 匯編程序MASM在翻譯某源程序模塊時,不能確定外部符號的地址,外部符號的地址有連接程序LINK來確定。
3、 庫文件
庫文件是一種特殊的OBJ文件。在程序設(shè)計中,可以把一些常用的程序段設(shè)計為子程序(過程),用匯編程序MASM把它們翻譯為OBJ文件,然后由庫管理程序LIB.EXE生成庫文件LIB。以后需使用某子程序時,直接調(diào)用,不必寫出這些子程序的代碼。由連接程序LINK把這些代碼加入可執(zhí)行文件EXE中。
§4.8.3 連接過程
連接程序LINK對所有OBJ模塊掃描兩遍。
第一遍掃描對所有段分配段地址,并建立一張"外部符號表"(又稱"全局符號表"),記錄外部符號的地址和屬性。
第二遍掃描確定與外部符號有關(guān)的機器指令,并創(chuàng)建"文件頭"(文件頭包含操作系統(tǒng)把EXE文件從磁盤調(diào)入內(nèi)存所需的信息)。
