




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第7章微型計算機(jī)匯編語言及匯編程序7.1宏匯編語言的基本語法7.2偽指令7.3宏指令7.4系統(tǒng)功能調(diào)用7.5匯編程序的功能及匯編過程7.6匯編語言程序設(shè)計習(xí)題匯編語言和機(jī)器語言相比,使用匯編語言來編寫程序的突出優(yōu)點就是可以使用符號;具體地說,就是可以用助記符來表示指令的操作碼和操作數(shù),可以用標(biāo)號和符號來代替地址、常量和變量。助記符一般都是表示一個操作的英文字母的縮寫,很便于識別和記憶。不過,用匯編語言編寫的程序不能由機(jī)器直接執(zhí)行,而必須翻譯成由機(jī)器代碼組成的目標(biāo)程序,這個翻譯過程稱為匯編。在微型機(jī)中,當(dāng)前絕大多數(shù)情況下,匯編過程是通過軟件自動完成的。用來把匯編語言編寫的程序自動翻譯成目的程序的軟件叫匯編程序。匯編過程的含義如圖7.1所示。圖7.1用匯編語言編寫的程序叫源程序。前面講的指令系統(tǒng)中的每條指令都是構(gòu)成源程序的基本語句。匯編語言的指令和機(jī)器語言的指令之間有一一對應(yīng)的關(guān)系。所以,匯編語言是和機(jī)器密切相關(guān)的,是面向機(jī)器的語言,CPU不同的機(jī)器有不同的匯編語言。采用匯編語言進(jìn)行程序設(shè)計時,我們可以充分利用機(jī)器的硬件功能和結(jié)構(gòu)特點,從而可有效地加快程序的執(zhí)行速度,減小目標(biāo)程序所占用的存儲空間。因此,與高級語言相比,匯編語言為我們提供了直接控制目標(biāo)代碼的手段,而且可以對輸入/輸出端口進(jìn)行控制,實時性能好,執(zhí)行速度快和節(jié)省存儲空間等明顯優(yōu)點。所以,匯編語言大量被用于編寫計算機(jī)系統(tǒng)程序、實時通信程序、實時控制程序等。8086和80286,80386,80486系統(tǒng)的匯編程序完全相同,簡稱作ASM-86。在此基礎(chǔ)上進(jìn)一步擴(kuò)展其功能,成為當(dāng)前廣泛使用的8086宏匯編程序,簡稱作MASM-86。圖7.2它與指令語句不同,偽指令語句(又叫命令語句)中的偽指令本身不產(chǎn)生對應(yīng)的機(jī)器目標(biāo)代碼。它僅僅是告訴匯編程序,對后面的指令語句和偽指令語句的操作數(shù)應(yīng)該如何產(chǎn)生機(jī)器目標(biāo)代碼。每一條偽指令語句共分4個字段,它的指令格式如圖7.2所示。7.1宏匯編語言的基本語法
7.1.1偽指令語句格式1.標(biāo)號名字段這是一個任選字段。標(biāo)號名后面不能用冒號“:”,這是它與指令語句的突出區(qū)別。不同的偽指令,標(biāo)號名可以是常量名、變量名、過程名、結(jié)構(gòu)名、記錄名等。它們可以作為指令語句和偽指令語句的操作數(shù),這時,標(biāo)號名就表示一個常量或存儲器地址。2.偽指令字段這是偽指令語句不可省略的主要成分。偽指令種類很多,如定義數(shù)據(jù)偽指令DB,DW,DD;段定義偽指令SEGMENT;定義過程偽指令PROC;…。它們是偽指令語句要求匯編程序完成的具體操作命令。3.操作數(shù)字段本字段是否需要,需要幾個,需要什么樣的操作數(shù)等都由偽指令字段中偽指令來確定。操作數(shù)可以是一個常數(shù)(二進(jìn)制、十進(jìn)制、十六進(jìn)制等)、字符串、常量名、變量名、標(biāo)號、一些專用的符號(如BYTE,F(xiàn)AR,PARA等)。4.注釋字段這是一個任選字段,它必須以分號為開始,它的作用與指令語句的注釋字段相同。7.1.2常數(shù)、變量和標(biāo)號常數(shù)、變量和標(biāo)號是匯編語言能識別的數(shù)據(jù)項,它是指令和偽指令語句中操作數(shù)的基本組成部分。一個數(shù)據(jù)項包含有它的數(shù)值和屬性兩部分,這兩部分對一條語句匯編成機(jī)器目標(biāo)代碼都有直接關(guān)系。1.常數(shù)常數(shù)是沒有任何屬性的純數(shù)值。在匯編期間,它的值已能完全確定,且在程序運行中,它也不會發(fā)生變化。它可以有以下幾種類型:(1)二進(jìn)制數(shù):以字母B結(jié)尾的,由0和1組成的數(shù)字序列,如01011010B。(2)八進(jìn)制數(shù):以字母O或Q結(jié)尾的0~7數(shù)字序列,如723Q,35O。(3)十進(jìn)制數(shù):0~9數(shù)字序列,可以用字母D結(jié)尾,也可以沒有結(jié)尾字母,如129,129D。(4)十六進(jìn)制數(shù):以字母H結(jié)尾,由數(shù)字0~9和字母A~F(或a~f)組成的序列,如3A5BH,0FH。為了區(qū)別由A~F組成的是一個十六進(jìn)制數(shù)還是一個標(biāo)識符,凡以字母A~F為起始的一個十六進(jìn)制數(shù),必須在前面冠以數(shù)字“0”,否則匯編程序認(rèn)作標(biāo)識符。(5)實數(shù):它由整數(shù)、小數(shù)和指數(shù)3部分組成,這是計算機(jī)中的浮點表示法。實數(shù)一般用十進(jìn)制數(shù)形式給出,實數(shù)的格式如下:±整數(shù)部分小數(shù)部分E±指數(shù)部分其中,整數(shù)和小數(shù)部分形成這個數(shù)的值,稱作尾數(shù),它可以是帶符號的數(shù)。指數(shù)部分由指數(shù)標(biāo)識符E開始,它表示了值的大小,如5.213E-4。(6)字符串常數(shù):用引號括起來的一個或多個字符。這些字符以ASCII碼形式存儲在內(nèi)存中。如“AB”,在內(nèi)存中就是41H,42H。在程序中,常數(shù)主要出現(xiàn)在:(1)指令語句中源操作數(shù)中作立即數(shù),它應(yīng)與目的操作數(shù)的位數(shù)相一致,可以是8位或16位,例如:MOVAX,0A5F1H(2)在指令語句的基址加變址的尋址方式中作位移量,例如:MOVBX,[SI+32H](3)在數(shù)據(jù)定義偽指令中,例如:DB12H;定義一個字節(jié)數(shù)據(jù)DW1234H;定義一個字?jǐn)?shù)據(jù)DD12345678H;定義一個雙字?jǐn)?shù)據(jù)DB′ABCD′;定義4個字節(jié)的字符串?dāng)?shù)據(jù)2.變量變量是代表存放在某些存儲單元的數(shù)據(jù),這些數(shù)據(jù)在程序運行期間隨時可以修改。為了便于對變量的訪問,它常常以變量名的形式出現(xiàn)在程序中,它可以認(rèn)為是存放數(shù)據(jù)存儲單元的符號地址。(1)變量的定義與預(yù)置:定義變量就是給變量分配存儲單元,且對這個存儲單元賦于一個符號名——變量名,同時將這些存儲單元預(yù)置初值。定義變量是用數(shù)據(jù)定義偽指令DB,DW,DD等。例如:VAR-DATASEGMENTDATA1DB12HDATA2DB34HDATA3DW5678HVAR-DATAENDS經(jīng)過定義的變量,每個變量均有3個屬性:①段屬性(SEG):表示變量存放在哪一個邏輯段中(p155)(即變量所在段的段基值。例如,變量名為DATA1,DATA2,DATA3的3個變量都存放在VAR-DATA邏輯段中(用SEGMENT/ENDS偽指令定義一個邏輯段)。當(dāng)在指令中要對這些變量進(jìn)行存取操作時,事先要把它們所在段的段基值存放在某一個段寄存器(如DS)中。②偏移量屬性(OFFSET):表示變量在邏輯段中離段起始點的字節(jié)數(shù)。例如,變量DATA1的偏移量為0,而DATA2的偏移量為1,DATA3的偏移量為2。上述段和偏移量兩個屬性就構(gòu)成了變量的邏輯地址。③類型屬性(TYPE):表示變量占用存儲單元的字節(jié)數(shù)。這一屬性是由數(shù)據(jù)定義偽指令DB,DW,DD來規(guī)定的。變量DATA1,DATA2是用DB定義的,它的類型屬性為字節(jié);而DATA3是用DW定義的,類型屬性為字;如果用DD定義,類型屬性為雙字。(2)數(shù)據(jù)定義偽指令:這種偽指令主要為數(shù)據(jù)項分配存儲單元并預(yù)置初值。由這種偽指令構(gòu)成的語句格式是:DB變量名DW表達(dá)式1,表達(dá)式2,…DD其中表達(dá)式1,表達(dá)式2,…是給變量賦予的初值。表達(dá)式可以有如下幾種情況:①數(shù)值表達(dá)式。例如:DA_BYTEDB50H,50DA_WORDDW0A3F1H,4981H變量DA-BYTE的內(nèi)容為50H,它的下一個字節(jié)為32H(即DA-BYTE+1字節(jié)單元的內(nèi)容為十進(jìn)制50)。DA-WORD字單元內(nèi)容為0A3F1H(低字節(jié)為F1H,高字節(jié)為0A3H)它的下一字單元內(nèi)容為4981H(即DA-WORD+2字單元)。②?表達(dá)式:不帶引號的?表示可預(yù)置任何內(nèi)容。例如:DA_BDB?,?DA_WDW?,?第1條語句是要求匯編程序分配兩個字節(jié)單位,第2條語句是要求分配兩個字單元。這些單元里現(xiàn)在可以是任意值。③字符串表達(dá)式:對于DB偽指令,為字符串中每一個字符分配一個字節(jié)單元。字符串必須是用引號括起來且不超過255個字符。字符串自左至右以字符的ASCII碼按地址遞增的排列順序依次存放。例如:STRING1DB′ABCDEF′在存儲器中存放的情況如圖7.3(a)所示。對于DW偽指令,可以給兩個字符組成的字符串分配兩個字節(jié)存儲單元,而且這兩個字符ASCII碼的存儲順序是前一字符在高字節(jié),后一字符在低字節(jié),每一個數(shù)據(jù)項不能多于兩個字符。例如:STRING2DW′AB′,′CD′,′EF′在存儲器中存放的情況如圖7.3(b)所示。對于DD偽指令,僅可給兩個字符組成的字符串分配4個字節(jié)單元,且這兩個字符ASCII碼是存儲在兩個低字節(jié)(存儲順序與DW偽指令相同)中,兩個高字節(jié)均存放00H。例如:STRING3DD′AB′,′CD′在圖7.3(c)顯示了它們存儲器中的存放情況。圖7.3④帶DUP表達(dá)式:DUP是定義重復(fù)數(shù)據(jù)操作符。在表達(dá)式中,使用DUP操作符格式是:DB變量名DW表達(dá)式1DUP(表達(dá)式2)DD其中表達(dá)式1是重復(fù)的次數(shù),表達(dá)式2是重復(fù)的內(nèi)容。例如:D_B1DB20HDUP(?)D_B2DB10HDUP(′ABCD′)D_W1DW10HDUP(4)第1語句表示保留20H個字節(jié),每個字節(jié)可預(yù)置任意內(nèi)容。第2語句是重復(fù)10H個字符串“ABCD”,共占有40H個字節(jié)。第3語句是重復(fù)10H個字單元,每個單元預(yù)置為4,共占有20H個字節(jié)。3.標(biāo)號標(biāo)號是一條指令目標(biāo)代碼的符號地址,它常作為轉(zhuǎn)移指令(含子程序調(diào)用指令)的操作數(shù)。例如:LOP1:……LOOPLOP1JNENEXTNEXT:……與變量類似,每個標(biāo)號亦具有3個屬性:(1)段屬性(SEG):表示這條指令目標(biāo)代碼在哪個邏輯段中。(2)偏移量屬性(OFFSET):表示這條指令目標(biāo)代碼的首字節(jié)在段內(nèi)離段起始點的字節(jié)數(shù)。同樣,上述兩個屬性構(gòu)成了這條指令目標(biāo)代碼首字節(jié)的邏輯地址。(3)距離屬性:表示本標(biāo)號可作為段內(nèi)或段間的轉(zhuǎn)移特性。距離屬性分為兩種:①NEAR(近):本標(biāo)號只能被標(biāo)號所在段的轉(zhuǎn)移和調(diào)用指令所訪問(即段內(nèi)轉(zhuǎn)移);②FAR(遠(yuǎn)):本標(biāo)號可被其他段(不是標(biāo)號所在段)的轉(zhuǎn)移和調(diào)用指令訪問(即段間轉(zhuǎn)移)。7.1.3表達(dá)式與運算符表達(dá)式由操作數(shù)和運算符組成,在匯編時一個表達(dá)式得到一個值。下面結(jié)合運算符講述表達(dá)式。用一個運算符可以對一個操作數(shù)或幾個操作數(shù)進(jìn)行運算,這就構(gòu)成了一個表達(dá)式,從而得到一個新的值。ASM86中分6類運算符,包括算術(shù)運算符、邏輯運算符、關(guān)系運算符、分析運算符、組合運算符和分離運算符,它們在匯編時完成相應(yīng)運算。1.算術(shù)運算符+,-,*,/是加減乘除運算符。MOD是除法取余運算符。例如,32MOD5=2。SHL是左移操作符。例如,21HSHL2=84H。SHR是右移操作符。2.邏輯運算符AND是邏輯“與”操作符。例如,24HAND0FH=04H。OR是邏輯“或”操作符。例如,24HOR0FH=2FH。XOR是“異或”操作符。例如,24HXOR0FH=2BH。NOT是邏輯“非”操作符。例如,NOT24H=0DBH。3.關(guān)系運算符關(guān)系運算是邏輯判定式的,當(dāng)為“真”時結(jié)果取0FFFFH,當(dāng)為“假”時結(jié)果取0。關(guān)系運算是數(shù)值型的。EQ等于。例如,已賦給符號PP為25,則25EQPP=0FFFFH。NE不等于。例如,25NEPP=0。LT小于。例如,25LT26=0FFFFH。LE小于等于。例如,25LEPP=0FFFFH。GT大于。例如,26GT25=0FFFFH。GE大于等于。例如,24GEPP=0。4.分析運算符(1)SEG求段基址格式:SEG〈符號名〉(2)OFFSET求偏移地址格式:OFFSET〈符號名〉(3)TYPE求符號名類型值格式:TYPE〈符號名〉(4)SIZE求為符號名分配的字節(jié)數(shù)格式:SIZE〈符號名〉為符號名定義的數(shù)據(jù)項必須是用重復(fù)格式DUP()定義的。(5)LENGTH求為符號名分配的項數(shù)格式:LENGTH〈符號名〉為符號名定義的數(shù)據(jù)項必須是用重復(fù)格式DUP()定義的。SIZE〈符號名〉=(LENGTH〈符號名〉)*(TYPE〈符號名〉)5.組合運算符組合運算符是用來改變或建立符號名的新類型。(1)定義符號名為新類型格式:〈類型〉PTR〈符號名〉例如,設(shè)內(nèi)存變量D1是字節(jié)屬性,把它的兩個字節(jié)內(nèi)容送到AX中。MOVAX,WORDPTRD1這里的符號名可以是間址、變址尋址、基址加變址尋址表示的存儲器操作數(shù)。(2)指定新類型與PTR類似,可為某個符號名建立新類型。格式:THIS〈類型〉例如:LABCEQUTHISBYTELABDDW4321H,2255HMOVAL,LABC;AL=21HMOVAX,LABD;AX=4321H符號名LABC與LABD有相同的段地址和偏移地址,但LABC是字節(jié)類型,而LABD是字類型。6.分離運算符(1)LOW取低字節(jié)格式:LOW〈表達(dá)式〉(2)HIGH取高字節(jié)格式:HIGH〈表達(dá)式〉例如:設(shè)SSY=2050HMOVAL,LOW3080H;AL=80HMOVAH,HIGHSSY;AH=20HMOVCL,LOW3A4BH;CL=4BH7.匯編運算符的優(yōu)先級見表7.2(見書第160頁)所示。7.2偽指令偽指令沒有對應(yīng)的機(jī)器指令,它不是由86系列CPU來執(zhí)行,而是由MASM-86識別,并完成相應(yīng)的功能。它在很大程度上規(guī)定了MASM-86的性能,因此也可稱之為匯編命令。MASM-86中允許使用的偽指令相當(dāng)豐富,必須搞清楚這些偽指令的功能及其用法,才能編制出高質(zhì)量的匯編語言源程序。MASM-86中使用的偽指令可分成14類,下面逐一進(jìn)行介紹。1.符號定義偽指令(賦值語句)(1)〈名字〉EQU〈表達(dá)式〉(2)〈名字〉=〈表達(dá)式〉該語句把表達(dá)式的值賦給符號名,在同一程序中,用EQU語句賦值的符號名不能被重新賦值,但用“=”號賦值的符號名可以被重新賦值?!啊础怠碧柋硎敬隧棽荒苣J(rèn),但該符號不需要輸入。2.內(nèi)存數(shù)據(jù)定義偽指令(1)字節(jié)定義偽指令[名字]DB〈表達(dá)式或數(shù)據(jù)項表〉表達(dá)式值或項表中的每一項是一個字節(jié)數(shù),它們從符號名地址開始按字節(jié)連續(xù)存放,直到表中數(shù)據(jù)項結(jié)束(地址遞增方向)。方括號[]表示該項可以默認(rèn)。(2)字定義偽指令[名字]DW〈表達(dá)式或數(shù)據(jù)項表〉除表達(dá)式值或項表中的每一項是兩個字節(jié)數(shù)之外,其它與DB偽指令相同。(3)4字節(jié)定義偽指令[名字]DD〈表達(dá)式或數(shù)據(jù)項表〉表達(dá)式值或項表的每一項是4個字節(jié)數(shù),該語句可以定義有小數(shù)點的十進(jìn)制數(shù)或用科學(xué)表示法表示的數(shù)據(jù),此時在匯編時被譯成4字節(jié)浮點數(shù),尾數(shù)在低地址一端,階碼在高地址一端。浮點數(shù)格式見7.1節(jié)中所述。例如:N1DD25ABH,0A002677HN2DD2.5,3.2E+2(4)8字節(jié)定義偽指令[名字]DQ〈表達(dá)式或數(shù)據(jù)項表〉表達(dá)式值或數(shù)據(jù)項表的每一項是8字節(jié)數(shù),各項從小地址一端連續(xù)存放,允許浮點數(shù)形式,與DD偽指令相同。高4個字節(jié)填0。(5)10字節(jié)定義偽指令[名字]DT〈表達(dá)式或數(shù)據(jù)項表〉表達(dá)式值或數(shù)據(jù)項表的每一項是10字節(jié)數(shù),允許浮點數(shù)形式,與DQ偽指令相同;若項表中的數(shù)據(jù)項是十進(jìn)制整數(shù)書寫的,匯編程序按組合的BCD碼格式存放,最低字節(jié)在高地址一端存放,數(shù)據(jù)的最高字節(jié)的最高位是符號位,“0”表示正,“1”表示負(fù)。表達(dá)式或數(shù)據(jù)項表多于一項時,項與項之間用逗號“,”或空格分隔,表達(dá)式或數(shù)據(jù)項重復(fù)書寫時,可用重復(fù)格式簡寫。例如:在指令中引用上述定義的符號名時,必須考慮符號名的類型,否則會出現(xiàn)錯誤提示。例如:MOVAX,D1;D1類型錯誤MOVAX,WORDPTRD1;正確3.段定義偽指令存儲器在邏輯上是分段的,各段的定義由偽指令實現(xiàn)。格式:〈段名〉SEGMENT[定位方式][連接方式][‘類別名’]…〈段名〉ENDS段定義偽指令為程序的匯編和連接說明了段名、分段的各種屬性以及分段的開始和結(jié)束。段名是自定義符,開始的段名與結(jié)束的段名必須相同。段的長度不超過64KB。SEGMENT后面的參數(shù)是可選項。(1)定位方式(定位類型):定位方式指定段的起始地址邊界,方式有4種。PAGE——指定起始地址的低8位是0,即其值能被256整除(稱為頁邊界)。PARA——指定起始地址的低4位是0,即其值能被16整除(稱為段邊界)。這是系統(tǒng)隱含定位方式。WORD——指定起始地址的最低位是0,即其值能被2整除(稱為字邊界)。BYTE——指定起始地址是任意值。以上4種邊界如下所示:××××××××××××00000000PAGE××××××××××××××××0000PARA×××××××××××××××××××0WORD××××××××××××××××××××BYTE(2)連接方式(組合類型):連接方式告訴連接程序本段與其他段可按某種方式連接,它有6種選擇。PUBLIC——告訴連接程序把本段與其他同名同類別的段連接起來,公用一個段的起點地址,形成一個物理段。STACK——表示本段是堆棧段,連接方式同PUBLIC,連接后的段起始地址在SS寄存器中。連接程序要求源程序至少要有一個堆棧段,否則提示錯誤,此時,系統(tǒng)取約定堆棧段值??杖?NONE)——表示本段不與任何段連接,這是系統(tǒng)隱含連接方式。COMMON——表示本段與同名同類別的段共用同一段起始地址,即同名同類段相重疊,段的長度是最長段的長度。MEMORY——表示本段在連接時定位在所有段之上,即高地址處。AT表達(dá)式——表示本段定位在表達(dá)式值指定的段地址處。(3)‘類別名’:類別名是合法的自定義符,它必須用單引號括起來。凡是類別名相同的段在連接時均按先后順序連接起來。4.段寄存器說明偽指令格式:ASSUME段寄存器:段定義名1[,段寄存器:段定義名2,…]該偽指令告訴匯編程序在匯編時,段寄存器CS:,DS:,SS:和ES:應(yīng)具有的符號段基址,以便匯編指令時確定段和建立錯誤信息。但是段寄存器實際值(CS除外)還要由傳送指令在執(zhí)行程序時賦值。5.過程(子程序)定義偽指令格式:〈過程名〉PROC[NEAR](或[FAR])〈過程名〉ENDP過程名是自定義符。定義過程是為實現(xiàn)子程序調(diào)用而設(shè)的。調(diào)用格式為:CALL〈過程名〉過程由RET指令返回,它可以不是最后一條指令,它在過程中可以設(shè)多點返回。過程起始名和終止名必須相同。類型NEAR和FAR默認(rèn)時系統(tǒng)約定是近過程,當(dāng)選NEAR時,過程是段內(nèi)調(diào)用,過程中的RET是段內(nèi)返回。當(dāng)選FAR時,過程是段間調(diào)用,過程中的RET是段間返回。6.模塊開始偽指令格式:NAME模塊名該偽指令指明程序模塊的開始,并指出模塊名。模塊名是自定義符,它不能是系統(tǒng)保留字,每次匯編只能出現(xiàn)一次。若該偽指令默認(rèn),則取TITLE語句中的頁標(biāo)題前6個字符;若沒有TITLE語句,則取源程序文件名為模塊名。7.模塊結(jié)束偽指令格式:END[啟動標(biāo)號或過程名]該偽指令告訴匯編程序源文件結(jié)束,并給出執(zhí)行程序的入口位置。啟動地址只有在主模塊才有意義。8.定位偽指令格式:ORG〈表達(dá)式〉該偽指令把以下語句定義的內(nèi)存數(shù)據(jù)或程序,從表達(dá)式指定的起點(偏移地址)開始連續(xù)存放,直至遇到新的ORG指令。表達(dá)式的值是一個無符號數(shù)。9.列表偽指令(1)建立標(biāo)題格式:TITLE標(biāo)題為列表文件每頁第一行定義大標(biāo)題。(2)建立小標(biāo)題格式:SUBTTL小標(biāo)題為列表文件每頁定義小標(biāo)題,輸出在大標(biāo)題之后。(3)自動排版(行數(shù)、列數(shù))格式:PAGE行數(shù),行字?jǐn)?shù)為列表文件定義每頁行數(shù)(10~255)和每行字符數(shù)(60~132),默認(rèn)值是66行,80列。10.系統(tǒng)隱含進(jìn)位制偽指令格式:·RADIX表達(dá)式定義在源程序中書寫數(shù)據(jù)時的隱含進(jìn)位制方式。表達(dá)式的值是2~16之間的十進(jìn)制數(shù),要遇到新的·RADIX語句后才改變隱含進(jìn)位制。例如,表達(dá)式取值是8時,書寫默認(rèn)后綴的數(shù)據(jù)是八進(jìn)制而不是十進(jìn)制。11.連接偽指令連接偽指令主要解決多模塊的連接問題,對一個大程序來說,往往要分模塊編程,分模塊調(diào)試,最后再系統(tǒng)連接與調(diào)試。連接偽指令為多模塊連接進(jìn)行說明。(1)公用符號偽指令格式:PUBLIC〈符號名1[,符號名2,…]〉本模塊用PUBLIC偽指令說明的自定義符號名可由其他程序模塊引用,沒有說明的符號名不能被其他模塊引用。符號名可以是變量名、標(biāo)號、過程名或符號常量等。(2)引用符號偽指令格式:EXTRN〈符號名1:類型[,符號名2:類型…]〉在本模塊引用的在其他模塊定義的符號名必須用EXTRN進(jìn)行說明,否則不能引用。此外還應(yīng)注意,所引用的外模塊定義的符號名還應(yīng)是用PUBLIC偽指令說明過的。類型是指符號名的類型,它們可以是:內(nèi)存變量型:BYTE,WORD,DWORD過程型:NEAR,F(xiàn)AR數(shù)值型:ABS(3)插入偽指令(或稱包含偽指令)格式:INCLUDE〈模塊名〉在本模塊匯編時,把另一模塊插入該偽指令處一起匯編,被插入的模塊可以是不完整的。(4)合段偽指令(或稱組合偽指令)格式:組名GROUP〈段名1[,段名2,段名3,…]〉把其后指定的段組合在一個64KB的物理段中,組名和段名都是自定義符,但不可重名。12.記錄偽指令(1)記錄定義偽指令格式:記錄名RECORD〈字段名1:字段寬[,字段名2:字段寬,…]〉記錄定義偽指令完成對內(nèi)存單元二進(jìn)制位的定義,這在實際應(yīng)用中可以實現(xiàn)按位開關(guān)量或按位組合信息的處理。記錄名和字段名是自定義符,字段寬度是1~16常數(shù)。記錄是把1~16個二進(jìn)制位分為段并賦于一個字段名。記錄定義偽指令不真正為記錄分配內(nèi)存單元,它只是在匯編時進(jìn)行記錄名、字段名以及記錄長度的說明。(2)記錄存儲單元分配及賦值格式:[變量名]記錄名〈字段值表〉變量名是自定義符,字段值表中的各字段值賦給記錄的各字段中,其順序與記錄定義的順序相同,若字段值表中的某些項默認(rèn),則默認(rèn)值為0。應(yīng)用時尖括號“〈〉”不能默認(rèn)。例如:TANRECORDX∶6,Y∶4,Z∶6APTAN〈5,10,,〉BPTAN〈12,,20〉此例在存儲器中分配兩個記錄,每個記錄長是兩個字節(jié)(16位)。(3)記錄操作符①WIDTH格式:WIDTH記錄名(或字段名)用該操作符可求出記錄或字段所占的位數(shù)。例如:MOVAX,WIDTHTAN;AX←16MOVBH,WIDTHY;BH←4②MASK格式:MASK記錄字段名用該操作符可返回記錄字段位或使用情況,它是8位或16位二進(jìn)制數(shù),1表示是該字段位,0表示不是該字段位。例如:MOVAL,MASKZ;AL←00111111BMOVBL,MASKX;BL←11111100B13.結(jié)構(gòu)偽指令結(jié)構(gòu)偽指令是把多個數(shù)據(jù)定義語句組織成一個結(jié)構(gòu),而把每一個數(shù)據(jù)定義語句稱為一個結(jié)構(gòu)字段,內(nèi)存變量名稱為字段名。(1)結(jié)構(gòu)定義格式:結(jié)構(gòu)名STRUC〈數(shù)據(jù)定義語句〉結(jié)構(gòu)名ENDS結(jié)構(gòu)定義不真正為結(jié)構(gòu)分配存儲空間,它是在匯編時進(jìn)行結(jié)構(gòu)說明的。(2)結(jié)構(gòu)存儲單元分配及賦值格式:[變量名]結(jié)構(gòu)名〈字段值表〉變量名是自定義符,字段值表的各字段值賦給結(jié)構(gòu)的各字段中,其順序與結(jié)構(gòu)定義的順序相同,若字段值表中某些項默認(rèn),則保留初始值。應(yīng)用時尖括號“〈〉”不能默認(rèn)。例如:TAN1STRUCD1DB2,25,10HD2DB′WTAN′SYYDB?TAN1ENDSSUNTAN1〈,′DOG1′,2〉CATTAN1〈,′beg′,〉在存儲器中分配了兩個結(jié)構(gòu)單元。(3)結(jié)構(gòu)引用格式:結(jié)構(gòu)變量名結(jié)構(gòu)字段名例如:MOVDH,SUNSYY;DH←2MOVAL,CATSYY;AL←014.塊注釋偽指令格式:COMMENT定界符注釋定界符定界符是自定義任何非空字符。例如,COMMENT/注釋文/例題Data segmentD1 db 1D2 db 2D3 db ?Data endsCode segment assume ds:data,cs:codeBegin:mov ax,data mov ds,ax lea si,d1 mov al,[si] inc si mov bl,[si] add al,bl mov [si+1],al hltCode ends endbegin7.3宏指令為了簡化匯編語言源程序的書寫,把一些頻繁出現(xiàn)的程序段定義為“宏指令”,當(dāng)程序中遇到這個程序段時,只需用一條宏調(diào)用語句,這樣有效地縮短了源程序的長度,使源程序易讀,也減少了由于重復(fù)書寫而引起的錯誤。從某種意義上講,它與前述的“過程”有相似之處,也可以將構(gòu)成一條宏指令的程序段定義為一個“過程”,但兩者具有明顯的區(qū)別,主要表現(xiàn)如下:(1)宏調(diào)用語句由宏匯編程序MASM86中的宏處理程序來識別,并完成相應(yīng)的處理;而調(diào)用過程的CALL語句由CPU來執(zhí)行。(2)匯編語言源程序在匯編過程中要將宏指令所代替的程序段匯編成相應(yīng)的機(jī)器代碼,并插入到源程序的目標(biāo)代碼中,每次調(diào)用均要插入,這樣,使用宏調(diào)用并不能縮短目標(biāo)代碼的長度。但被定義的“過程”經(jīng)匯編后的機(jī)器代碼是與主程序分開而獨立存在的,其目標(biāo)代碼在存儲器中只需保留一份,因此,采用過程調(diào)用能有效地縮短目標(biāo)代碼的長度,即節(jié)省內(nèi)存空間,而宏指令卻沒有這一優(yōu)點。(3)過程調(diào)用時需要保留程序的斷點和現(xiàn)場,待過程執(zhí)行完畢還要恢復(fù)現(xiàn)場和斷點,這些操作需要耗費CPU的時間,而宏調(diào)用則不需進(jìn)行這些操作。因此,過程調(diào)用可節(jié)省程序占用的存儲空間,但會降低程序的執(zhí)行速度;而宏調(diào)用不能節(jié)省存儲空間,卻能有較快的執(zhí)行速度。(4)在每次宏調(diào)用時允許修改有關(guān)參數(shù),使得同一條宏指令在各次調(diào)用過程中可完成不同的操作;而“過程”一旦被定義,一般不允許修改。因此,任何一個“過程”在各次調(diào)用中只能完成完全相同的功能。從上述特點可看出,當(dāng)需要多次執(zhí)行的程序段比較長,對速度要求不很高,并且不要求修改參數(shù)的情況下,宜采用過程調(diào)用方式;若要求多次執(zhí)行的程序段比較短,或希望在各次調(diào)用中能修改某些參數(shù)時,則宜采用宏調(diào)用方式。在使用高級語言時,各語句的定義(即它對應(yīng)哪些機(jī)器指令)是由相應(yīng)的編譯程序去處理的,但宏指令卻不一樣,它需要定義。宏指令的使用要經(jīng)過如下3個步驟:(1)宏定義:對各個宏指令進(jìn)行定義,并分別起一個名字;(2)宏調(diào)用:在需要使用的地方,通過宏指令名來調(diào)用它;(3)宏擴(kuò)展:由宏匯編程序用宏定義中的指令來代替宏調(diào)用中的宏指令名。下面介紹各種宏語句及其功能。1.宏代換語句格式:宏名MACRO[形式參數(shù)1,形式參數(shù)2,…]宏體(指令序列)ENDM功能:宏代換語句為指令序列定義一個宏名,稱為宏指令,宏名可以像指令一樣在程序中引用。形式參數(shù)是任選項,可用來代換宏體中某些參數(shù)或符號。當(dāng)代換指令中的符號時,在其前面需加一個宏代換符&。例如:AHMACROY,XMOVCL,XRO&YCLENDM經(jīng)宏代換語句定義的宏名,在應(yīng)用時可直接引用,稱為宏調(diào)用。宏調(diào)用時,形式參數(shù)要用實在參數(shù)取代,順序也應(yīng)與形式參數(shù)順序相同。例如:AHR,5源程序在匯編后,在引用宏名的地方,插入了宏體,它在.LST文件列表時可以看到,其中有+號的指令便稱為宏擴(kuò)展。宏指令可以嵌套,并可與子程序聯(lián)合嵌套。2.局域符號定義語句格式:LOCAL符號1[,符號2,…]功能:指出符號1,符號2,…僅在宏代換中有意義,其目的是在宏擴(kuò)展時不會引起符號重復(fù)定義的錯誤。LOCAL語句必須緊跟在MACRO之后。3.刪除宏定義語句格式:PURGE宏定義名1[,宏定義名2,…]功能:刪除(注銷)程序中引用的宏指令,使之在宏調(diào)用的地方不再生成宏擴(kuò)展。4.退出宏定義格式:EXITM功能:在宏體或重復(fù)定義的語句中,遇到EXITM語句時,終止以后的宏擴(kuò)展。5.重復(fù)定義語句(1)格式:REPT〈表達(dá)式〉}指令序列ENDM功能:重復(fù)執(zhí)行REPT與ENDM之間的指令,表達(dá)式是重復(fù)次數(shù)。6.重復(fù)定義語句(2)格式:IRP形式參數(shù),〈參數(shù)1,參數(shù)2,…〉}指令序列ENDM功能:重復(fù)執(zhí)行IRP與ENDM之間的語句,每次重復(fù),將一個參數(shù)代入形式參數(shù)中,直到最后一個參數(shù)代換完為止。7.重復(fù)定義語句(3)格式:IRPC形式參數(shù),字符串}指令序列ENDM功能:重復(fù)執(zhí)行IRPC與ENDM之間的語句,每次重復(fù),將一個字符代入形式參數(shù)中,直到最后一個字符代換完為止。8.包含匯編語句格式:INCLUDE文件名功能:在程序匯編時,把INCLUDE指示的文件插入該語句處一起匯編。7.4系統(tǒng)功能調(diào)用為給編寫匯編語言源程序提供方便,MS-DOS系統(tǒng)中設(shè)置了幾十個內(nèi)部子程序,它們可完成I/O設(shè)備管理、存儲管理、文件管理和作業(yè)管理等功能。對我們來說,它們是幾十個獨立中斷服務(wù)程序,它們的入口已由系統(tǒng)置入中斷入口地址表中,在匯編語言源程序中可用軟中斷指令調(diào)用它們。一般我們常用的軟中斷指令有8條,系統(tǒng)規(guī)定它們的中斷類型碼為20H~27H,它們各自的功能及入口/出口參數(shù)如表7-3所示(見書第168頁)。從表7-3中可看出,這些軟中斷完全隱蔽了設(shè)備的物理特性和接口方式,調(diào)用它們時只需要先設(shè)置好入口參數(shù),隨后安排一條軟中斷指令“INTn”(n=20~27H),即可轉(zhuǎn)去執(zhí)行相應(yīng)的子程序。其中“INT21H”是系統(tǒng)功能調(diào)用,它本身包含80多個子程序,每個子程序?qū)?yīng)一個功能號,其編號從0~57H。系統(tǒng)功能調(diào)用中的幾十個子程序成為匯編語言程序員的重要工具,程序員不必了解所使用設(shè)備的物理特性、接口方式及內(nèi)存分配等,不必編寫繁鎖的控制程序。調(diào)用它們時采用統(tǒng)一的格式,只需使用以下3個語句:(1)傳送入口參數(shù)到指定寄存器中;(2)功能號送入AH寄存器中;(3)INT21H。有的子程序無入口參數(shù),則只需安排后兩個語句,調(diào)用結(jié)束后,系統(tǒng)將出口參數(shù)送到指定寄存器中或從屏幕顯示出來。例如:2號系統(tǒng)功能調(diào)用可用如下指令:調(diào)用結(jié)果是將DL寄存器中的可打印字符通過屏幕顯示輸出(或打印機(jī)打印輸出)。下面選擇一部分常用的系統(tǒng)功能調(diào)用作簡要說明:1.鍵盤輸入單字符這是1號系統(tǒng)功能調(diào)用,使用格式如下所示:它沒有入口參數(shù),執(zhí)行1號系統(tǒng)功能調(diào)用時,系統(tǒng)等待鍵盤輸入,待程序員按下任何一鍵,系統(tǒng)先檢查是否Ctrl-Break鍵,如果是則退出,否則將鍵入字符的ASCII碼置入AL寄存器中,并在屏幕上顯示該字符。2.鍵盤輸入字符串這是0AH號系統(tǒng)功能調(diào)用,其功能是將鍵盤輸入的字符串寫入到內(nèi)存緩沖區(qū)中,因此必須事先在內(nèi)存儲器中定義一個緩沖區(qū)。其第1字節(jié)給定該緩沖區(qū)中能存放的字節(jié)個數(shù),第2字節(jié)留給系統(tǒng)填寫實際鍵入的字符個數(shù),從第3個字節(jié)開始用來存放鍵入的字符串,最后鍵入回車鍵表示字符串結(jié)束。如果實際鍵入的字符數(shù)不足填滿緩沖區(qū)時,則其余字節(jié)填“0”;如果實際鍵入的字符數(shù)超過緩沖區(qū)的容量,則超出的字符將被丟失,而且響鈴,表示向程序員發(fā)出警告。0AH號系統(tǒng)功能調(diào)用的使用格式如下所示:……BUFDB20DB?定義緩沖區(qū)DB20DUP(?)……MOVDX,OFFSETBUFMOVAH,0AH0AH號系統(tǒng)功能調(diào)用INT21H以上程序中,由變量定義語句定義了一個可存放20個字節(jié)的緩沖區(qū),執(zhí)行到INT21H指令時,系統(tǒng)等待用戶鍵入字符串。程序員每鍵入一個字符,其相應(yīng)的ASCII碼將被寫入緩沖區(qū)中,待程序員最后鍵入回車鍵時,由系統(tǒng)輸出實際鍵入的字符數(shù),并將其寫入緩沖區(qū)的第2字節(jié)中。3.輸出單字符這是2號系統(tǒng)功能調(diào)用,使用格式如下所示:MOVDL,‘A’MOVAH,2INT21H執(zhí)行2號系統(tǒng)功能調(diào)用時,將置入DL寄存器中的字符從屏幕上顯示輸出(或打印機(jī)打印輸出)。4.輸出字符串這是9號系統(tǒng)功能調(diào)用,其功能是將指定的內(nèi)存緩沖區(qū)中的字符串從屏幕顯示輸出(或從打印機(jī)打印輸出)。緩沖區(qū)中的字符串以“$”字符作為結(jié)束標(biāo)志。9號系統(tǒng)功能調(diào)用的使用格式如下所示:……BUFDB′goodbye$′……MOVDX,OFFSETBUFMOVAH,9INT21H……執(zhí)行9號系統(tǒng)功能調(diào)用時,將內(nèi)存緩沖區(qū)BUF中存放的字符串(以“$”字符為結(jié)束)送屏幕顯示輸出(或送打印機(jī)打印輸出)。5.直接控制臺輸入/輸出單字符這是6號系統(tǒng)功能調(diào)用,如果(DL)=0FFH,則表示是從鍵盤輸入單字符送AL寄存器中;如果(DL)≠0FFH,則表示是將DL寄存器中內(nèi)容送屏幕顯示輸出。它們的使用格式如下:MOVDL,0FFHMOVAH,6;鍵盤輸入單字符送AL中INT21HMOVDL′A′MOVAH,6將DL中的字符“A”送屏幕顯示INT21H;6.無回顯直接控制臺輸入單字符這是7號系統(tǒng)功能調(diào)用,等待從標(biāo)準(zhǔn)輸入設(shè)備輸入單字符置入AL寄存器中,但不送屏幕顯示。其使用格式如下:MOVAH,7INT21H它沒有入口參數(shù),系統(tǒng)等待從控制臺標(biāo)準(zhǔn)輸入設(shè)備輸入單字符后,將其ASCII碼置入AL寄存器中。7.無回顯鍵盤輸入單字符這是8號系統(tǒng)功能調(diào)用,等待從鍵盤輸入單字符,將其ASCII碼置入AL寄存器中。但不送屏幕顯示,其使用格式如下:MOVAH,8INT21H它沒有入口參數(shù),與1號系統(tǒng)功能調(diào)用的區(qū)別僅在于鍵入的字符不送屏幕顯示。8.從串口輸入單字符這是3號系統(tǒng)功能調(diào)用,其使用格式如下:MOVAH,3INT21H它沒有入口參數(shù),系統(tǒng)將從異步通信口串行輸入的字符置入AL寄存器中。9.向串口輸出單字符這是4號系統(tǒng)功能調(diào)用,其使用格式如下:MOVDL,′$′MOVAH,4INT21H執(zhí)行結(jié)果將DL寄存器中的字符通過異步通信口串行輸出。10.返回操作系統(tǒng)這是4CH號系統(tǒng)功能調(diào)用,其使用格式如下:MOVAH,4CHINT21H它沒有入口參數(shù),執(zhí)行結(jié)果是結(jié)束當(dāng)前正在執(zhí)行的程序,并返回操作系統(tǒng)。屏幕顯示操作系統(tǒng)提示符(N>),N為當(dāng)前使用的驅(qū)動器名。11.設(shè)置日期這是2BH號系統(tǒng)功能調(diào)用,其功能是設(shè)置有效日期。例如,當(dāng)前需要設(shè)置的日期是1990年12月26日,那么應(yīng)將年號1990以裝配型BCD碼形式置入CX寄存器中,將月號12置入DH寄存器中,將日期26裝入DL寄存器中。其使用格式如下:MOVCX,1990HMOVDH,12HMOVDL,26HMOVAH,2BHINT21H執(zhí)行的結(jié)果是將有效日期設(shè)置為1990年12月26日,如果設(shè)置成功,則0→AL寄存器,否則0FFH→AL寄存器。從此以后日期會自動修改。12.取得日期這是2AH號系統(tǒng)功能調(diào)用,其功能是將當(dāng)前有效日期取到CX和DX寄存器中,存放格式與設(shè)置日期時相同,其使用格式如下:MOVAH,2AHINT21H它沒有入口參數(shù),執(zhí)行結(jié)果是將年號置入CX寄存器中,月份和日期置入DX寄存器中。13.設(shè)置時間這是2DH號系統(tǒng)功能調(diào)用,其功能是設(shè)置有效時間。例如,當(dāng)前有效時間是8點15分20.5秒,那么應(yīng)將小時數(shù)8置入CH寄存器中、分鐘數(shù)15置入CL寄存器中,秒數(shù)20置入DH寄存器中,百分之一秒數(shù)50置入DL寄存器中。其使用格式如下:MOVCX,0815HMOVDX,2050HMOVAH,2DHINT21H執(zhí)行結(jié)果是將當(dāng)前有效時間設(shè)置為8點15分20.5秒以后會自動修改時間。如果設(shè)置成功,則將AL寄存器內(nèi)容清“0”,否則將AL寄存器置全“1”。14.取得時間這是2CH號系統(tǒng)功能調(diào)用,其功能是將當(dāng)前時間置入CX和DX寄存器中,存放格式與設(shè)置時間相同。其使用格式如下:MOVAH,2CHINT21H它沒有入口參數(shù),執(zhí)行結(jié)果是將當(dāng)前時間送入CX和DX寄存器中供使用。其他的系統(tǒng)功能調(diào)用,有的不常用,有的比較繁鎖,不再一一說明。7.5匯編程序的功能及匯編過程
7.5.1匯編程序的功能匯編程序的主要功能是將由匯編語言(助記符)編寫的源程序翻譯成用機(jī)器語言(二進(jìn)制代碼)編寫的目標(biāo)程序。圖7.4可用以說明這個功能。圖7.4從圖7.4中可以看到,匯編語言源程序作為匯編程序(MASM或ASM)這個“翻譯”的輸入,而這個“翻譯”的輸出是3個文件。其中,目標(biāo)代碼文件就是機(jī)器碼文件,在目標(biāo)代碼文件中的地址數(shù)據(jù)還是浮動的(相對的),因此,它還不能直接運行;列表文件包含了程序的邏輯地址、代碼程序及源程序?qū)φ涨鍐?,并在該文件后附有引用符號表,該文件可用DOS的TYPE命令輸出;交叉索引文件包含了符號定義行號和引用行號,該文件不能用TYPE命令輸出,它需要執(zhí)行CREF文件后生成索引列表文件(.REF)才能輸出。匯編語言的程序一般要經(jīng)過編輯、匯編(MASM或ASM)、連接(LINK)和調(diào)試(DE-BUG)這些步驟,如圖7.5所示。圖7.5圖7.51.建立源程序文件建立源程序文件用編輯軟件完成,常用的編輯軟件有行編輯EDLIN,全屏幕編輯WORDSTAR等。2.匯編(MASM或ASM)源程序IBMPC微機(jī)提供了兩種匯編程序版本:一種是全型版本(MASM);另一種是小型版本(ASM)。全型版本比小型版本增加了宏匯編、條件匯編及錯誤信息全部打印輸出功能。小型版本占用存儲空間小,有64KB的內(nèi)存就可以運行,而全型版本至少要有90KB以上的內(nèi)存。匯編程序有兩種啟動方式:(1)提問方式在MS-DOS下輸入命令行:MASM或ASM這時,MS-DOS將裝入并啟動執(zhí)行匯編程序,然后匯編程序就逐次向用戶提問,用戶必須根據(jù)要求予以回答。在回答信息的最后,可輸入一個或多個開關(guān),匯編程序?qū)凑栈卮鹦畔⒓伴_關(guān)的定義做相應(yīng)處理。在回答提示信息時,可以使用以下兩個命令字符:;用于省略對后續(xù)提示的回答,僅取默認(rèn)值;CTRL-C當(dāng)因為輸入了錯誤的文件名或其他原因而想中途退出匯編程序時,按下CTRL-C鍵即可退出。(2)命令方式以命令方式啟動匯編程序時,必須在MS-DOS下打入下列格式的命令:MASM(或ASM)〈源文件〉,[〈目標(biāo)文件〉],[〈列表文件〉],[〈交叉參考文件〉][/開關(guān)]于是在裝入?yún)R編程序后將立即開始進(jìn)行匯編。命令中MASM(或ASM)后面的項目,分別順次對應(yīng)于提問方式中對各提示信息的回答,各項目之間用逗號隔開。/開關(guān)可放在任一項目之后。如果對某一提示信息采用默認(rèn)值,則只需在對應(yīng)的項目處連續(xù)輸入兩個逗號。例如:MASMFUN,,F(xiàn)UN/D/X,F(xiàn)UN3.程序連接連接程序LINK用來連接匯編程序生成的目標(biāo)代碼文件(.OBJ)以及指定的庫文件,產(chǎn)生一個可執(zhí)行的裝入文件(.EXE)。連接程序有3種啟動方式:(1)提問方式在MS-DOS下輸入命令行:LINK這時MS-DOS將把連接程序裝入內(nèi)存,并向用戶提問,用戶根據(jù)要求輸入相應(yīng)的回答。除了在匯編程序一段中敘述過的兩個命令字符以外,連接程序的回答信息中還可使用命令字符+號,它用以分隔多個要連接的目標(biāo)代碼模塊或庫文件。當(dāng)顯示器上一行輸入不下時還可使用+號另起一行。(2)命令方式以命令方式啟動連接程序時,必須在MS-DOS下輸入如下格式的命令:LINK〈目標(biāo)代碼模塊表〉,[〈裝入模塊名〉],[〈列表文件名〉],[〈庫文件名表〉][/開關(guān)]命令中LINK后面的各項目順次對應(yīng)于提問方式中對各提示信息的回答,各項目之間用逗號隔開。如對某一項提示信息采用默認(rèn)值,則只需在對應(yīng)的項目處連續(xù)輸入兩個逗號。例如:LINKFUN+TEXT+TABLE+CARE/P/M,,F(xiàn)UNLIST,COBLIB-LIB(3)文件方式以文件方式啟動LINK的命令格式為:LINK@〈文件名〉其中,文件名用來指出一個包含有對于LINK提示信息回答的正文文件,文件中每一行正文對應(yīng)一個回答,因而用戶可以不必一一回答LINK的提示,而由LINK程序直接從文件中取得回答。當(dāng)然,在使用文件方式之前,用戶必須建立一個這樣的響應(yīng)文件。4.執(zhí)行程序在DOS提示符下,鍵入連接程序所產(chǎn)生的可執(zhí)行文件的名字后,即可執(zhí)行該程序。例如:A:>ABCD(擴(kuò)展名EXE可默認(rèn))就會把文件ABCD.EXE裝入內(nèi)存,并從程序指定地址開始執(zhí)行。執(zhí)行程序其結(jié)果不一定正確,有時會“死機(jī)”。“死機(jī)”時要重新啟動機(jī)器,然后用DEBUG調(diào)試.EXE文件。5.調(diào)試程序調(diào)試程序DEBUG是專為宏匯編語言設(shè)計的一種調(diào)試手段,是我們必須掌握的一種調(diào)試工具。在操作系統(tǒng)提示符下,按如下格式鍵入命令:A:>DEBUG[驅(qū)動器名:][路徑][文件名[擴(kuò)展名]]例如:A:>DEBUGA:ABCD.EXE鍵入此命令后,就啟動了DEBUG程序。DOS的COMMAND.COM程序首先裝入DEBUG.COM文件,并把控制權(quán)交給DEBUG。DEBUG程序再裝入ABCD.EXE文件,但控制權(quán)并不交給ABCD.EXE,而是由DEBUG掌握著。在DEBUG程序中,為我們提供了18條子命令。利用這18條子命令,我們可以對程序進(jìn)行匯編和反匯編;可以觀察和修改內(nèi)存及寄存器的內(nèi)容;可以執(zhí)行或跟蹤程序,并觀察每一步執(zhí)行的結(jié)果;可以讀/寫盤上的扇區(qū)或文件等。但令人遺憾的是,如果被調(diào)試的文件是可執(zhí)行文件(.EXE文件),則調(diào)試好的文件不能寫回到盤上去。這是因為,可執(zhí)行文件是帶有重定位信息文件頭的,調(diào)試程序不能產(chǎn)生這些重定位信息,因此不能把它寫回到盤上去。惟一的辦法就是在調(diào)試過程中把發(fā)現(xiàn)的錯誤記載下來,待調(diào)試完畢后,重新編輯、匯編和連接,產(chǎn)生新的可執(zhí)行文件。7.6匯編語言程序設(shè)計在第4章中已經(jīng)講過,8086/8088/80286/80386等CPU把存儲器分成若干段,每個段是一個可獨立尋址的邏輯單位。段是8086系列匯編語言程序的基礎(chǔ),一個段就是一些指令和數(shù)據(jù)的集合,8086系列匯編語言源程序就是建立在段結(jié)構(gòu)的基礎(chǔ)上。所以,在編制匯編語言源程序時,首先要使用段定義偽指令和段尋址偽指令來構(gòu)成一個由若干指令和數(shù)據(jù)組成的程序。一個程序有幾個段,完全根據(jù)實際情況來確定,通常是按照程序中的用途來劃分段。如存放數(shù)據(jù)的段,作堆棧使用的段,存放程序的段,存放子程序的段等等。我們在剛開始編制程序時,不妨先設(shè)3~4個段,由4個段寄存器CS,DS,SS,ES分別存放這些段的段基值。這樣,構(gòu)造一個源程序的基本格式如下:DATASEGMENT}存放數(shù)據(jù)項的數(shù)據(jù)段DATAENDSEXTRASEGMENT}存放數(shù)據(jù)項的附加段EXTRAENDSSTACK1SEGMENTPARASTACK}作堆棧用的堆棧段STACK1ENDSCOSEGSEGMENTASSUME CS:COSEG,DS:DATAASSUME SS:STACK1,ES:EXTRABEING: MOVAX,DATA MOVDS,AX}存放指令序列COSEGENDSENDBEING上述4個段排列的先后順序可以是任意的?!纠?.1】(1)設(shè)計要求:在源程序中設(shè)置數(shù)據(jù)段、堆棧段及代碼段。在數(shù)據(jù)段中定義8個字節(jié)數(shù)據(jù),把這些數(shù)據(jù)轉(zhuǎn)換成十六進(jìn)制數(shù)的ASCII碼存在上述數(shù)據(jù)之后,然后在屏幕上顯示這些數(shù)據(jù)。顯示數(shù)據(jù)用DOS功能2號調(diào)用,每個數(shù)據(jù)用空格分隔。(2)程序流程:程序流程如圖7.6和圖7.7所示。(3)程序清單:二進(jìn)制數(shù)對十六進(jìn)制數(shù)轉(zhuǎn)換及顯示主程序如下:圖7.6圖7.71:NAMEEX1;程序命名偽指令,程序名為EX12:PAGE50,703:;4:DAT SEGMENTPARA′DAT′5:A1 DB12H,34H,56H,78H,9AH6:DB 0BCH,0DEH,0F0H7:B1=$-A1;賦值偽指令,求A1(符號地址)到當(dāng)前匯編指針地址($)的字節(jié)數(shù)8:B2=B1*2;求2倍B19:A2 DB B2 DUP(?);數(shù)據(jù)重復(fù)定義偽指令,定義ASCII碼字符區(qū)10:DAT ENDS11:;12:STACSEGMENTPARASTACK′STA′13:STA1DW100DUP(?)14:STACENDS15:;16:CODESEGMENT[]PARA′CODE′17:ASSUMECS:CODE,DS:DAT18:ASSUMESS:STAC,ES:DAT19:STARPROCFAR20:PUSHDS21:XORAX,AX22:PUSHAX23:MOVAX,DAT24:MOVDS,AX25:MOVES,AX26:LEASI,A127:LEADI,A228:MOVCX,B129:G1:MOVBL,230:MOVAL,[SI]31:MOVBH,AL32:PUSHCX33:MOVCL,434:RORAL,CL35:POPCX36:G2:ANDAL,0FH37:DAA;對AL兩位十進(jìn)制數(shù)(BCD)調(diào)整38:ADDAL,0F0H39:ADCAL,40H40:MOV[DI],AL41:INCDI42:MOVAL,BH43:DECBL44:JNZG245:INCSI46:LOOPG147:MOVSIOFFSETA2;A2的偏移地址送SI寄存器48:MOVCX,B249:CALLP150:RET顯示ASCII碼字符子程序如下:51:P1PROC52:MOVBL,253:G:MOVDL,[SI]54:MOVAH,255:INT21H56:INCSI57:DECBL58:JNZT59:MOVDL,′′60:MOVAH,261:INT21H62:MOVBL,263:T:LOOPG64:RET65:P1ENDP66:CODEENDS67:ENDSTAR子程序名:P1功能:顯示ASCII碼字符入口:SI指向ASCII碼區(qū)CX是ASCII碼區(qū)長【例7.2】(1)設(shè)計要求:設(shè)計多字節(jié)減法運算程序,要求程序能夠顯示運算數(shù)據(jù)和結(jié)果數(shù)據(jù)(以十六進(jìn)制形式)。分模塊設(shè)計要求:①多字節(jié)減法;②多字節(jié)顯示;③回車換行操作。其中回車換行模塊按近程設(shè)計,不要求獨立匯編,它在主模塊匯編時由包含偽指令I(lǐng)NCLUDE插入,并一同匯編。程序?qū)哟谓Y(jié)構(gòu)如圖7.8所示。圖7.8(2)程序流程圖7.9圖7.10(3)程序清單主程序:1:NAMEEX22:PAGE50,703:PUBLICD1,D2,N1,N24:EXTRNEX21:FAR5:EXTRNEX22:FAR6:;7:DAT SEGMENTPARA′DAT′8:D1 DB 88H,44H,66H,00H,99H9:N1=$-D110:D2 DB 22H,55H,88H11:N2=$-D212:DAT ENDS13:;14:STAC SEGMENTPARASTACK15:STA1 DW 100 DUP(?)16:STAC ENDS17:;18:CODE SEGMENTPARA′CODE′19:ASSUMECS:CODE,DS:DAT20:ASSUMESS:STAC,ES:DAT21:STAPROCFAR22:PUSHDS23:XORAX,AX24:PUSHAX25:MOVAX,DAT26:MOVDS,AX27:MOVES,AX28:STD29:LEASI,D130:ADDSI,N1-131:MOVCX,N132:CALLEX2133:CALLPP234:LEASI,D235:ADDSI,N2-136:MOVCX,N237:CALLEX2138:CALLPP239:CALLEX2240:LEASI,D141:ADDSI,N1-142:MOVCX,N143:CALLEX2144:RET45:STAENDP46:;47:INCLUDEPP2ASM48:CODEENDS49:END STA回車換行子程序(分模塊):1:PP2PROC2:MOVDL,0DH3:MOVAH,24:INT21H5:MOVDL,0AH6:MOVAH,27:INT21H8:RET9:PP2ENDP1:NAMEEX212:PAGE50,703:PUBLICEX214:CODESEGMENTPARA′CODE′5:ASSUMECS:CODE6:EX21PROCFAR7:PUSHAX8:PUSHDX9:F:LODSB10:CALLPP111:MOVDL,′′12:MOVAH,213:INT21H14:LOOPF15:POPDX16:POPAX17:RET18:EX21ENDP19:;分模塊EX21功能:多字節(jié)二進(jìn)制數(shù)ASCII碼轉(zhuǎn)換、顯示。入口:DS:SI指向數(shù)據(jù)區(qū)高地址一端,CX是長度20:PP1PROC21:PUSHBX22:PUSHCX23:MOVBL,AL子程序:PP124:MOVCL,4功能:8位二進(jìn)制數(shù)對十六進(jìn)制數(shù)25:SHRAL,CLASCII碼轉(zhuǎn)換、顯示。26:CALLP1入口:AL是8位二進(jìn)制數(shù)。27:MOVAL,BL28:CALLP129:POPCX30:POPBX31:RET32:PP1ENDP33:P1PROC子程序P134:PUSHAX功能:4位二進(jìn)制數(shù)對十六進(jìn)制數(shù)35:PUSHDXASCII碼轉(zhuǎn)換、顯示36:ANDAL,0FH入口:AL低4位是二進(jìn)制數(shù)37:CMPAL,1038:JBS子程序P139:ADDAL,7功能:4位二進(jìn)制數(shù)對十六進(jìn)制數(shù)40:S:ADDAL,30HASCII碼轉(zhuǎn)換、顯示41:MOVDL,AL入口:AL低4位是二進(jìn)制數(shù)42:MOVAH,243:INT21H44:POPDX45:POPAX46:RET47:P1ENDP48:CODEENDS49:END多字減法子程序(分模塊):1:NAME2:PUBLICEX223:EXTRND1:BYTE,D2:BYTE4:EXTRNN1:ABS,N2:ABS5:;6:CODESEGMENTPARA′CODE′7:ASSUMECS:CODE8:EX22PROCFAR9:LEASI,D110:LEADI,D211:MOVBX,N112:MOVCX,N213:MM:MOVAL,[DI]14:SBB[SI],AL15:INCDI16:INCSI17:DECBX18:LOOPMM19:M1:JZM220:JNCM221:SBBBYTEPTR[SI],022:INCSI23:DECBX24:JMPM125:M2:RET26:EX22ENDP27:CODEENDS28:END【例7.3】大小寫字母互換(1)設(shè)計要求:設(shè)內(nèi)存數(shù)據(jù)區(qū)有大小寫混合英文ASCII碼字母。將其轉(zhuǎn)換成全部大寫和全部小寫,并在屏幕顯示這3種字母。字母顯示用DOS功能9號調(diào)用。(2)程序算法:大小寫英文字母轉(zhuǎn)換,查ASCII碼字符表可知,字母A~Z的ASCII碼是41H~5AH,字母a~z的ASCII碼是61H~7AH。兩種字母轉(zhuǎn)換只需加減20H即可。(3)程序如下:1:TITLEEX32:PAGE50,703:;4:DATSEGMENTPARA′DAT′↑5:D0DB0DH,0AH6:D1DB′AKFDjfjjecJIDJkdkjkJD′,′$′設(shè)置大小寫混合字母7:DATENDS↓8:;9:STACSEGMENTPARASTACK′STAC′↑10:STA1DW100DUP(?)設(shè)置堆棧段11:STACENDS↓12:;13:CODESEGMENTPARA′CODE′14:ASSUMECS:CODE,DS:DAT15:ASSUMESS:STAC,ES:DAT16:STARFAR17:PUSHDS18:XORAX,AX19:PUSHAX20:MOVAX,DAT↓21:MOVDS,AX設(shè)置數(shù)據(jù)段地址22:MOVES,AX↑23:;↑24:CALLTT顯示大小寫混合字母(TT)25:LEADI,D1大寫字母轉(zhuǎn)換小寫字母(TT1)26:CALLTT1顯示小寫字母(TT)27:CALLTT小寫字母轉(zhuǎn)換大寫字母(TT2)28:LEADI,D1顯示大寫字母(TT)29:CALLTT230:CALLTT↓31:RET32:STARENDP33:;34:TT1PROC35:GO:MOVAL,[DI]↑36:CMPAL,′$′37:JZGO238:CMPAL,′A′39:JBGO140:CMPAL,′Z′大寫字母轉(zhuǎn)換小寫字母子程序41:JAGO1TT142:ADDBYTEPTR[DI],20H43:GO1:INCDI44:JMPGO45:GO2:RET46:TT1ENDP↓47:;48:TT2PROC↑49:GQ:MOVAL,[DI]50:CMPAL,′$”51:JZGQ252:CMPAL,′a′53:JBGQ154:CMPAL,′Z′小寫字母轉(zhuǎn)換大寫字母子程序55:JAGQ1TT256:SUBBYTEPTR[DI],20H57:GQ1:INCDI58:JMPGQ59:GQ2:RET60:TT2ENDP61:;↓62:TTPROC↑63:LEADX,DS顯示字符串子程序TT64:MOVAH,965:INT21H66:RET67:TTENDP↓68:CODEENDS69:ENDSTAR執(zhí)行程序:A>EX3AKFDjfjjecJIDJkdkjkJDakfdjfjjecjidjkdkjkjdAKFDJFJJECJIDJKDKJKJD【例7.4】表的處理表是數(shù)據(jù)(或信息代碼)元素的集合,按其元素排列順序可分為有序表和無序表。有序表是指表中元素之間有著某種規(guī)律的表,這是應(yīng)用時非常希望的。無序表是指表中元素之間無任何規(guī)律可尋的表,這給表的應(yīng)用帶來許多不便,但這種表在應(yīng)用中會經(jīng)常遇到,如隨機(jī)檢測到的各種物理參量等。表的元素類型有數(shù)值型的、字符型的或是代表某種意義信息代碼。表的應(yīng)用十分廣泛,如函數(shù)表、平方及立方表、對數(shù)表、程序轉(zhuǎn)移地址表、中斷向量表等。表的處理有以下幾個方面:①讀表:讀出表中某個或某些元素,進(jìn)行顯示或處理。②刪除:刪除表中某個或某些元素。③插入:在表中某個位置插入某些元素。④排序:把表中元素按某種規(guī)律重新排列。⑤搜索:從表中查找某種或某些元素。⑥對表中元素作某種要求的統(tǒng)計。例如,統(tǒng)計表中某種元素個數(shù)等。(1)讀表程序設(shè)計①設(shè)計要求設(shè)內(nèi)存DS:2000H地址開始有一個ASCII碼字符表(設(shè)表長不大于100字節(jié)),該表以*作結(jié)束標(biāo)志。統(tǒng)計表長并以十進(jìn)制數(shù)顯示。由鍵盤輸入兩位十進(jìn)制數(shù)指示表的位置,讀出該位置元素值并送屏幕顯示。②程序算法統(tǒng)計表長是從表首開始按字節(jié)計數(shù),用DAA指令對計數(shù)值進(jìn)行十進(jìn)制數(shù)調(diào)整,計數(shù)遇到*符結(jié)束。對十進(jìn)制計數(shù)值進(jìn)行ASCII碼轉(zhuǎn)換,送屏幕顯示。用DOS功能1號調(diào)用,從鍵盤輸入兩位十進(jìn)制數(shù),將其轉(zhuǎn)換成二進(jìn)制數(shù)后在表中定位,讀出該位置的元素(ASCII碼字符)并送屏幕顯示。③程序清單如下:1:NAMEEX4-12:PAGE50,703:;↑4:DATSEGMENTPARA′DAT′5:ORG2000H6:A1DB10DUP(′ABCDE′)設(shè)置數(shù)據(jù)段7:DB8DUP(′12345′)設(shè)置數(shù)據(jù)表及結(jié)束標(biāo)志*8:DB′*′9:DATENDS↓10:;11:STACSEGMENTPARASTACK↑12:STA1DW100DUP(?)設(shè)置堆棧段13:STACENDS↓14:;15:CODESEGMENT[]PARA′CODE′↑16:ASSUMECS∶CODE,DS∶DAT17:ASSUMESS∶STAC,ES∶DAT設(shè)置代碼段18:STAPROCFAR↓19:PUSHDS↓20:XORAX,AX保護(hù)DOS返回地址21:PUSHAX↑22:MOVAX,DAT↑23:MOVDS,AX置數(shù)據(jù)段值24:MOVES,AX↓25:LEASI,A1↑26:XORAX,AX27:MOVAH,′*′28:Q1:CMPAH,[SI]29:JZQ2統(tǒng)計表長30:INCSI(十進(jìn)制)31:ADDAL,132:DAA33:JMPQ1↓34:Q2:MOVBL,AL↑35:MOVCL,436:SHRAL,CL37:ORAL,30H38:MOVDL,AL39:MOVAH,240:INT21H十進(jìn)制數(shù)轉(zhuǎn)換ASCII碼41:ANDBL,0FH送屏幕顯示42:ORBL,30H43:MOVDL,BL44:MOVAH,245:INT21H46:CALLP10↓47:MOVCL,2↑48:Q3:MOVAH,1鍵盤輸入(DOS功能1號)49:INT21H↓50:CMPAL,30H↑51:JBQ352:CMPAL,39H鍵盤輸入判別,非0—9字符53:JAQ3重新輸入54:DECCL55:JZQ4↓56:ANDAL,0FH↑57:MOVAH,10鍵盤輸入數(shù)字對二進(jìn)制數(shù)轉(zhuǎn)換58:MULAH(十位數(shù))59:MOVBL,AL60:JMPQ3↓61:Q4∶ANDAL,0FH↑62:ADDAL,BL63:DECAL鍵盤輸入數(shù)字對二進(jìn)制數(shù)轉(zhuǎn)換64:LEASI,A1(個位數(shù))65:MOVAH,066:ADDSI,AX↓67:MOVDL,′′↑68:MOVAH,2顯示空格69:INT21H↓70:MOVDL,[SI]↑71:MOVAH,2讀表元素72:INT21H↓73:RET74:STAENDP75:;76:P10PROC↑77:MOVDL,0DH78:MOVAH,279:INT21H輸出回車換行子程序80:MOVDL,0AH81:MOVAH,282:INT21H83:RET↓84:P1085:CODEENDS86:ENDSTA①設(shè)計要求設(shè)內(nèi)存數(shù)據(jù)區(qū)DS∶2000H地址開始有150個ASCII碼字符,該表以$符結(jié)束。刪除表中第31至45元素,從表首插入5個“!”符,顯示表刪除插入前后的內(nèi)容,由鍵盤輸入一個字符,刪除表中的這個元素,顯示表內(nèi)容。②程序算法刪除表中元素,只要把后面的元素向前移動,覆蓋要刪除的元素。表插入元素,先把指定位置以后的全部元素向后移動,留出空位,再把要插入的元素插入。當(dāng)刪除表中某類元素時,要對表進(jìn)行全面搜索,然后刪去所要刪除的該類元素。③程序清單如下:1:NAMEEX4-22:PAGE50,703:;4:DATSEGMENTPARA′DAT′↑5:ORG2000H設(shè)置數(shù)據(jù)段6:A0DB0DH,0AH設(shè)置字符表7:A1DB10DUP(′QWERTYUIO,′)設(shè)置表結(jié)束符$8:DB5DUP(′ASDFGHJKL,′)9:DB′$′10:DATENDS11:;↓12:STACSEGMENTPARASTACK↑13:STA1DW100DUP(?)設(shè)置堆棧段14:STACENDS↓15:;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 河道垃圾清理施工方案
- 外墻保溫真石漆勞務(wù)分包合同
- 房屋居間租賃服務(wù)合同
- 嘉興拆煙囪施工方案
- 合同協(xié)議生產(chǎn)合同
- 心理學(xué)認(rèn)知過程與個性發(fā)展題庫
- 人力資源行業(yè)數(shù)據(jù)統(tǒng)計表一覽(按職位類型)
- 個人學(xué)習(xí)成長記錄表
- 吉林壓花地坪施工方案
- 建筑勞務(wù)木工班組合同
- 上海市農(nóng)村房地一體宅基地確權(quán)登記工作實施方案
- 2025年湖南司法警官職業(yè)學(xué)院單招職業(yè)技能測試題庫必考題
- 數(shù)學(xué)-廣東省2025年深圳市高三年級第一次調(diào)研考試(深圳一模)試題和答案
- 全國第三屆職業(yè)技能大賽(無人機(jī)駕駛(植保)項目)選拔賽理論考試題庫(含答案)
- 液壓氣動技術(shù)課程設(shè)計
- 作物栽培學(xué)復(fù)習(xí)資料完整版要點
- 安全生產(chǎn)工作指導(dǎo)手冊
- 全國電子百拼中學(xué)組練習(xí)題
- 硬筆書法校本教材(共24頁)
- 淺析高中生財經(jīng)素養(yǎng)現(xiàn)狀與影響因素
- 汽車倒車防撞報警器的設(shè)計--本科畢業(yè)設(shè)計(論文)
評論
0/150
提交評論