




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5章匯編語言的基本語法本章主要內(nèi)容(1)匯編語言的主要特點(diǎn)(2)匯編語言源程序的結(jié)構(gòu)(3)匯編語言的基本語法(4)匯編語言程序的上機(jī)過程5.1匯編語言的特點(diǎn)匯編語言(AssembleLanguage)
一種面向機(jī)器的程序設(shè)計(jì)語言,是一種用符號(hào)表示的低級(jí)程序設(shè)計(jì)語言(機(jī)器語言的符號(hào)化描述),通常是為特定計(jì)算機(jī)或計(jì)算機(jī)系列專門設(shè)計(jì)的。用匯編語言編寫的程序不能由機(jī)器直接執(zhí)行,而必須經(jīng)匯編程序翻譯成機(jī)器語言程序。匯編語言指令與翻譯成的機(jī)器語言指令之間基本是一一對(duì)應(yīng)的關(guān)系。匯編過程示意:采用匯編語言進(jìn)行程序設(shè)計(jì)的優(yōu)點(diǎn):(1)可充分利用機(jī)器的硬件功能和結(jié)構(gòu)特點(diǎn),加快程序的執(zhí)行速度,減少目標(biāo)程序所占用的存儲(chǔ)空間。(2)常用來編寫實(shí)時(shí)控制程序、實(shí)時(shí)通信程序,有時(shí)也用來編制某些系統(tǒng)軟件程序。缺點(diǎn):1.編程效率低(與人們描述計(jì)算過程的需要差距大);2.與機(jī)器硬件的具體結(jié)構(gòu)聯(lián)系過于緊密
——在一種結(jié)構(gòu)的機(jī)器上開發(fā)的程序極難移植到另一種不同結(jié)構(gòu)的機(jī)器上去。5.2匯編語言程序結(jié)構(gòu)和基本語法5.2.1示例程序示例程序DATASEGMENT
;數(shù)據(jù)段
NUMDW0011101000000111B;即3A07HNOTESDB‘Theresultis:’,’$’DATAENDSSTACK
SEGMENTSTACK;堆棧段
STADB50DUP(?)TOPEQULENGTHSTASTACK
ENDSCODE
SEGMENT
;代碼段
ASSUMECS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVAX,STACKMOVSS,AX
示例程序(續(xù))
MOVAX,TOPMOVSP,AX
MOVDX,OFFSETNOTES;顯示提示信息
MOVAH,9HINT21H
MOVBX,NUM;將數(shù)裝入BXJLEDISPLAY
MOVCH,4;CH作循環(huán)計(jì)數(shù)器ADDAL,07H;在A~F之間ROTATE:DISPLAY:MOVCL,4;CL中放移位位數(shù)
MOVDL,AL;顯示這個(gè)16進(jìn)制數(shù)
ROLBX,CLMOVAH,2MOVAL,BLINT21HANDAL,0FH;AL中為一位16進(jìn)制數(shù)DECCHADDAL,30H;轉(zhuǎn)換為ASCII碼值JNZROTATECMPAL,’9’;是0~9的數(shù)碼?MOVAX,4C00H;返回DOSINT21H
CODE
ENDS
;代碼段結(jié)束
ENDBEGIN;模塊結(jié)束從這個(gè)示例程序可以清楚地看到匯編語言源程序的兩個(gè)組成特點(diǎn):分段結(jié)構(gòu)和語句行。1.分段結(jié)構(gòu)匯編語言源程序是按段來組織的。8086匯編源程序最多可由4種段組成,即代碼段、數(shù)據(jù)段、附加段和堆棧段,并分別由段寄存器CS、DS、ES和SS中的值來指示段的起始地址。每段有一個(gè)名字,并以符號(hào)SEGMENT表示段的開始,以ENDS作為段的結(jié)束符號(hào)。兩者的左邊都必須有段的名字,而且名字必須相同。示例程序中共有3個(gè)段,分別是數(shù)據(jù)段(段名為DATA)、堆棧段(段名為STACK)和代碼段(段名為CODE)。2.語句行匯編語言源程序的段由若干語句行組成。語句是完成某種操作的指示和說明,是構(gòu)成匯編語言程序的基本單位。上述示例程序共有38行,即共有38個(gè)語句行。匯編語言程序中的語句可分為三種類型:指令語句、偽指令語句和宏指令語句。對(duì)于指令語句,匯編程序?qū)阉g成機(jī)器代碼,并由CPU識(shí)別和執(zhí)行;而對(duì)于偽指令語句(又稱指示性語句),匯編程序并不把它翻譯成機(jī)器代碼,它僅向匯編程序提供某種指示和引導(dǎo)信息,使之在匯編過程中完成相應(yīng)的操作,如給特定符號(hào)賦予具體數(shù)值,將特定存儲(chǔ)單元放入所需數(shù)據(jù)等。關(guān)于宏指令的特點(diǎn),將在后面介紹。5.2.2基本概念
1.標(biāo)識(shí)符標(biāo)識(shí)符也叫名字,是程序員為了使程序便于書寫和閱讀所使用的一些字符串。例如示例程序中的數(shù)據(jù)段名DATA,代碼段名CODE,程序入口名BEGIN,標(biāo)號(hào)名DISPLAY等。定義一個(gè)標(biāo)識(shí)符有如下幾點(diǎn)要求:(1)標(biāo)識(shí)符可以由字母A~Z,a~z,數(shù)字0~9,專用字符
?,·,@,$,_(下劃線)等符號(hào)構(gòu)成;(2)標(biāo)識(shí)符不能以數(shù)字開始,如果用到字符“·”則必須是第一個(gè)字符;(3)標(biāo)識(shí)符長(zhǎng)度不限,但是宏匯編程序僅識(shí)別前31個(gè)字符。2.保留字保留字(也稱關(guān)鍵字)是匯編語言中預(yù)先保留下來的具有特殊含義的符號(hào),只能作為固定的用途,不能由程序員任意定義。例如示例程序中的SEGMENT、MOV、INT、END等。所有的寄存器名、指令操作助記符、偽指令操作助記符、運(yùn)算符和屬性描述符等都是保留字。3.數(shù)的表示
在沒有8087、80287、80387等數(shù)學(xué)協(xié)處理器的系統(tǒng)中,所有的常數(shù)必須是整數(shù)。表示一個(gè)整數(shù)應(yīng)遵循如下的規(guī)則:(1)默認(rèn)情況下是十進(jìn)制,但可以使用偽指令“RADIXn”來改變默認(rèn)基數(shù),其中n是要改變成的基數(shù);
(2)如果要用非默認(rèn)基數(shù)的進(jìn)位制來表示一個(gè)整數(shù),則必須在數(shù)值后加上基數(shù)后綴。字母B,D,H,O或Q分別是二進(jìn)制、十進(jìn)制、十六進(jìn)制、八進(jìn)制的基數(shù)后綴。例如示例程序中的0011101000000111B、21H等整數(shù);(3)如果一個(gè)十六進(jìn)制數(shù)以字母開頭,則必須在前面加數(shù)字0。例如,十六進(jìn)制數(shù)F應(yīng)表示為0FH;
(4)可以用單引號(hào)括起一個(gè)或多個(gè)字符來組成一個(gè)字符串常數(shù),如示例程序中的’Theresultis:’。字符串常數(shù)以串中字符的ASCII碼值存儲(chǔ)在內(nèi)存中,如’The’在內(nèi)存中就是54H、68H、65H。在有數(shù)學(xué)協(xié)處理器的系統(tǒng)中,可以使用實(shí)數(shù)。實(shí)數(shù)的類型有多種,但其一般的表示形式如下:±整數(shù)部分.小數(shù)部分E±指數(shù)部分例如,實(shí)數(shù)5.213×10-6表示為5.213E-6。
4.表達(dá)式和運(yùn)算符表達(dá)式由運(yùn)算符和操作數(shù)組成,可分為數(shù)值表達(dá)式和地址表達(dá)式兩種類型。操作數(shù)可以是常數(shù)、變量名或標(biāo)號(hào)等,在內(nèi)容上可能代表一個(gè)數(shù)據(jù),也可能代表一個(gè)存儲(chǔ)單元的地址。變量名和標(biāo)號(hào)都是標(biāo)識(shí)符。例如示例程序中的變量名NUM、NOTES和標(biāo)號(hào)BEGIN、ROTATE等。數(shù)值表達(dá)式能被計(jì)算產(chǎn)生一個(gè)數(shù)值的結(jié)果。而地址表達(dá)式的結(jié)果是一個(gè)存儲(chǔ)器的地址,如果這個(gè)地址的存儲(chǔ)區(qū)中存放的是數(shù)據(jù),則稱它為變量;如果存放的是指令,則稱它為標(biāo)號(hào)。匯編語言程序中的運(yùn)算符的種類很多,可分為算術(shù)運(yùn)算符、邏輯運(yùn)算符、關(guān)系運(yùn)算符、分析運(yùn)算符、綜合運(yùn)算符、分離運(yùn)算符、結(jié)構(gòu)和記錄中專用運(yùn)算符和其他運(yùn)算符等幾類,如教材中表5-1所示。如果在一個(gè)表達(dá)式中出現(xiàn)多個(gè)上述的運(yùn)算符,將根據(jù)它們的優(yōu)先級(jí)別由高到低的順序進(jìn)行運(yùn)算,優(yōu)先級(jí)別相同的運(yùn)算符則按從左到右的順序進(jìn)行運(yùn)算。運(yùn)算符的優(yōu)先級(jí)如教材中表5-2所示。下面對(duì)各種運(yùn)算符做簡(jiǎn)單說明。(1)算術(shù)運(yùn)算符算術(shù)運(yùn)算符的運(yùn)算對(duì)象和運(yùn)算結(jié)果都必須是整數(shù)。其中求模運(yùn)算MOD就是求兩個(gè)數(shù)相除后的余數(shù)。移位運(yùn)算SHL和SHR可對(duì)數(shù)進(jìn)行按位左移或右移,相當(dāng)于對(duì)此數(shù)進(jìn)行乘法或除數(shù)運(yùn)算,因此歸入算術(shù)運(yùn)算符一類。注意,8086指令系統(tǒng)中也有助記符為SHL和SHR的指令,但與表達(dá)式中的移位運(yùn)算符是有區(qū)別的。表達(dá)式中的移位運(yùn)算符是偽指令運(yùn)算符,它是在匯編過程中由匯編器進(jìn)行計(jì)算的;而機(jī)器指令中的移位助記符,它是在程序運(yùn)行時(shí)由CPU執(zhí)行的操作。例如:
MOVAL,00011010BSHL2;相當(dāng)于MOVAL,01101000BSHLAL,1;移位指令,執(zhí)行后AL中為D0H本例第一行中的“SHL”是偽指令的移位運(yùn)算符,它在匯編過程中由匯編器負(fù)責(zé)計(jì)算;第二行中的“SHL”是機(jī)器指令的移位助記符,它在程序運(yùn)行時(shí)由CPU負(fù)責(zé)執(zhí)行。(2)邏輯運(yùn)算符邏輯運(yùn)算符對(duì)操作數(shù)按位進(jìn)行邏輯運(yùn)算。指令系統(tǒng)中也有助記符為NOT、AND、OR、XOR的指令,兩者的區(qū)別同上述“移位運(yùn)算符”與“移位指令助記符”的區(qū)別一樣。例如:
MOVAL,NOT10100101B;相當(dāng)于MOVAL,01011010BNOTAL;邏輯運(yùn)算指令(3)關(guān)系運(yùn)算符關(guān)系運(yùn)算符對(duì)兩個(gè)操作數(shù)進(jìn)行比較,若條件滿足,則運(yùn)算結(jié)果為全“1”;若條件不滿足,則運(yùn)算結(jié)果為全“0”。例如:
MOVAX,5EQ101BMOVBH,10HGT16MOVBL,0FFHEQ255MOVAL,64HGE100等效于:
MOVAX,0FFFFHMOVBH,00HMOVBL,0FFHMOVAL,0FFH(4)分析運(yùn)算符分析運(yùn)算符可以“分析”出運(yùn)算對(duì)象的某個(gè)參數(shù),并把結(jié)果以數(shù)值的形式返回,所以又叫數(shù)值返回運(yùn)算符。主要有SEG、OFFSET、LENGTH、TYPE和SIZE5個(gè)分析運(yùn)算符。下面分別予以介紹。①SEG運(yùn)算符加在某個(gè)變量或標(biāo)號(hào)之前,返回該變量或標(biāo)號(hào)所在段的段基值。②OFFSET運(yùn)算符加在某個(gè)變量或標(biāo)號(hào)之前,返回該變量或標(biāo)號(hào)的段內(nèi)偏移地址。③LENGTH運(yùn)算符加在某個(gè)變量之前,返回的數(shù)值是一個(gè)變量所包含的單元(可以是字節(jié)、字、雙字等)數(shù),對(duì)于變量中使用DUP的情況,將返回以DUP形式表示的第一組變量被重復(fù)設(shè)置的次數(shù);而對(duì)于其他情況則返回1。④TYPE運(yùn)算符加在某個(gè)變量或標(biāo)號(hào)之前,返回變量或標(biāo)號(hào)的類型屬性,返回值與類型屬性的對(duì)應(yīng)關(guān)系如表5-3所示。
表5-3TYPE運(yùn)算符的返回值
變量類型返回值標(biāo)號(hào)類型返回值字節(jié)(BYTE)字(WORD)雙字(DWORD)四字(QWORD)十字節(jié)(TBYTE)
124810近(NEAR)遠(yuǎn)(FAR)-1(FFH)-2(FEH)⑤SIZE運(yùn)算符加在某個(gè)變量之前,返回?cái)?shù)值是變量所占的總字節(jié)數(shù),且等于LENGTH和TYPE兩個(gè)運(yùn)算符返回值的乘積。例如:
K1DB4DUP(0)K2DW10DUP(?)MOVAH,LENGTHK1;LENGTHK1=4MOVAL,SIZEK1;TYPEK1=1,SIZEK1=LENGTHK1×TYPEK1
=4×1=4MOVBH,LENGTHK2;LENGTHK2=10MOVBL,SIZEK2;TYPEK2=2,SIZEK2=LENGTHK2×TYPEK2
=10×2=204條MOV指令分別等效于:
MOVAH,4MOVAL,4MOVBH,10MOVBL,20(5)綜合運(yùn)算符綜合運(yùn)算符可用于指定變量或標(biāo)號(hào)的屬性,因此也叫屬性運(yùn)算符。主要有PTR和THIS兩個(gè)綜合運(yùn)算符,下面分別予以介紹。①PTR運(yùn)算符用來規(guī)定內(nèi)存單元的類型屬性,格式是:
類型PTR符號(hào)名其含義是將PTR左邊的類型屬性賦給其右邊的符號(hào)名。例如:指令“MOVBYTEPTR[1000H],0”使1000H字節(jié)單元清0;指令“MOVWORDPTR[1000H],0”使1000H和
1001H兩個(gè)字節(jié)單元清0。②THIS運(yùn)算符可以用來改變存儲(chǔ)區(qū)的類型屬性。格式是:
符號(hào)名EQUTHIS類型其含義是將THIS右邊的類型屬性賦給EQU左邊的符號(hào)名,并且使該符號(hào)名的段基值和偏移量與下一個(gè)存儲(chǔ)單元的地址相同。THIS運(yùn)算符并不為它所在語句中的符號(hào)名分配存儲(chǔ)空間,其功能是為下一個(gè)存儲(chǔ)單元另起一個(gè)名字并另定義一種類型,從而可以使同一地址單元具有不同類型的名字,便于引用。例如:
AEQUTHISBYTEBDW1234H
此時(shí),A的段基值和偏移量與B完全相同。相當(dāng)于給變量B起了個(gè)別名叫A,但A的類型是字節(jié)型,而B的類型為字型;以后當(dāng)用名字A來訪問存儲(chǔ)器數(shù)據(jù)時(shí),實(shí)際上訪問的是B開始的數(shù)據(jù)區(qū),但訪問的類型是字節(jié)。換句話說,對(duì)于B開始的數(shù)據(jù)區(qū)既可用名字A以字節(jié)類型來訪問,也可用名字B以字的類型來訪問。如對(duì)于上面的例子,可有如下的訪問結(jié)果:MOVAL,A;指令執(zhí)行后,AL=34HMOVAX,B;指令執(zhí)行后,AX=1234H當(dāng)THIS語句中的符號(hào)名代表一個(gè)標(biāo)號(hào)時(shí),則能夠賦予該標(biāo)號(hào)的類型為NEAR或FAR,例如:BEGINEQUTHISFARADDCX,100從而使ADD指令有一個(gè)FAR屬性的地址BEGIN,于是允許其他段通過JMP指令(如“JMPFARPTRBEGIN”)遠(yuǎn)跳轉(zhuǎn)到這里來。注意,PTR運(yùn)算符只在使用它的語句中有效,而THIS運(yùn)算符則影響從使用處往后的程序段。(6)分離運(yùn)算符HIGH運(yùn)算符用來從運(yùn)算對(duì)象中分離出高字節(jié),LOW運(yùn)算符用來從運(yùn)算對(duì)象中分離出低字節(jié)。例如:MOVAL,HIGH1234H;相當(dāng)于MOVAL,12HMOVAL,LOW1234H
;相當(dāng)于MOVAL,34H
(7)其他運(yùn)算符①短轉(zhuǎn)移說明運(yùn)算符SHORT用來說明一個(gè)轉(zhuǎn)移指令的目標(biāo)地址與本指令的字節(jié)距離在-128~+127之間。例如:JMPSHORTLABEL2②圓括號(hào)運(yùn)算符()用來改變運(yùn)算符的優(yōu)先級(jí)別,()中的運(yùn)算符具有最高的優(yōu)先級(jí),與常見的算術(shù)運(yùn)算的()的作用相同。③方括號(hào)運(yùn)算符[]常用來表示間接尋址。例如:MOVAX,[BX]MOVAX,[BX+SI]
④段超越前綴運(yùn)算符“:”表示后跟的操作數(shù)由指定的段寄存器提供段基值。例如:
MOVBL,DS:[BP];把DS:BP單元中的值送BL5.語句和任何高級(jí)語言一樣,語句是構(gòu)成匯編語言程序的基本單位。匯編語言程序中的每個(gè)語句由四項(xiàng)組成,一般格式如下:[名字項(xiàng)]操作項(xiàng)[操作數(shù)項(xiàng)][;注釋]其中除“操作項(xiàng)”外,其他部分都是可選的?!懊猪?xiàng)”是一個(gè)標(biāo)識(shí)符,它可以是一條指令的標(biāo)號(hào)或一個(gè)操作數(shù)的符號(hào)地址等;操作項(xiàng)是某種操作的助記符,例如加法指令的助記符ADD等;而“操作數(shù)項(xiàng)”由一個(gè)或多個(gè)操作數(shù)組成,它給所執(zhí)行的操作提供原始數(shù)據(jù)或相關(guān)信息;注釋由分號(hào)“;”開始,其后可為任意的文本。若一行的第一個(gè)字符為分號(hào),則整行被視為注釋。也可用COMMENT偽操作定義多行注釋。注釋會(huì)被匯編程序忽略,但對(duì)于讀、寫和調(diào)試源程序有很大幫助。提倡在源程序中給出充分的、恰如其份的注釋。
程序中語句之間以及一條語句的各項(xiàng)之間都必須用分隔符分隔。其中分號(hào)“;”是注釋開始的分隔符,冒號(hào)“:”是標(biāo)號(hào)與匯編指令之間的分隔符,逗號(hào)“,”用來分隔兩個(gè)操作數(shù),“空格”(space鍵)和“制表符”(Tab鍵)則可用于為了表示的清晰而在任意兩部分之間插入若干個(gè)空格或制表符。匯編語言程序中的語句分為指令語句、偽指令語句和宏指令語句三種,下面分別詳細(xì)介紹。5.2.3指令語句指令語句是要求CPU執(zhí)行某種操作的命令,可由匯編程序翻譯成機(jī)器代碼。其具體格式如圖5.2所示。
圖5.2指令語句格式1.標(biāo)號(hào)標(biāo)號(hào)是一個(gè)標(biāo)識(shí)符,是給指令所在地址取的名字。標(biāo)號(hào)后必須跟冒號(hào)“:”。標(biāo)號(hào)具有三種屬性:段基值、偏移量及類型(NEAR和FAR)。2.操作助記符操作助記符表示本指令的操作類型。它是指令語句中唯一不可缺少的部分。必要時(shí)可在指令助記符的前面加上一個(gè)或多個(gè)前綴,從而實(shí)現(xiàn)某些附加操作。3.操作數(shù)操作數(shù)是參加指令運(yùn)算的數(shù)據(jù),可分為立即操作數(shù)、寄存器操作數(shù)、存儲(chǔ)器操作數(shù)3種。有的指令不需要顯式的操作數(shù),如指令XLAT;有的指令則需要不止一個(gè)的顯式操作數(shù),這時(shí)需用逗號(hào)“,”分隔兩個(gè)操作數(shù),如指令“ADDAX,BX”。關(guān)于操作數(shù),還有下面幾個(gè)術(shù)語和概念應(yīng)進(jìn)一步說明,它們是常數(shù)、常量、變量、標(biāo)號(hào)及偏移地址計(jì)數(shù)器$。⑴常數(shù)編程時(shí)已經(jīng)確定其值,程序運(yùn)行期間不會(huì)改變其值的數(shù)據(jù)對(duì)象稱為常數(shù)。80x86CPU允許定義的常數(shù)類型有整數(shù)、字符串及實(shí)數(shù)。在沒有協(xié)處理器的環(huán)境中它不能處理實(shí)數(shù),只能處理整數(shù)及字符串常數(shù)。字符串常數(shù)可以用單引號(hào)括起一個(gè)或多個(gè)字符來組成。(2)常量常量是用符號(hào)表示的常數(shù)。它是程序員給出的一個(gè)助記符作為一個(gè)確定值的標(biāo)識(shí),其值在程序執(zhí)行過程中保持不變。常量可用偽指令語句EQU或“=”來定義。例如:AEQU7或A=7都可將常量A的值定義為常數(shù)7。(3)
變量編程時(shí)確定其初始值,程序運(yùn)行期間可修改其值的數(shù)據(jù)對(duì)象稱為變量。實(shí)際上,變量代表的就是存儲(chǔ)單元。與存儲(chǔ)單元有其地址和內(nèi)容兩重特性相對(duì)應(yīng),變量有變量名和值兩個(gè)側(cè)面,其中變量名與存儲(chǔ)單元的地址相聯(lián)系,變量的值則對(duì)應(yīng)于存儲(chǔ)單元的內(nèi)容。
變量可由偽指令語句DB、DW、DD等來定義,通常定義在數(shù)據(jù)段和附加段。所謂定義變量,其實(shí)就是為數(shù)據(jù)分配存儲(chǔ)單元,且對(duì)這個(gè)存儲(chǔ)單元取一個(gè)名字,即變量名。變量名實(shí)際上就是存儲(chǔ)單元的符號(hào)地址。存儲(chǔ)單元的初值由程序員來預(yù)置。變量有如下屬性:①段基值:指變量所在段的段基值;②偏移地址:指變量所在的存儲(chǔ)單元的段內(nèi)偏移地址;③類型:指變量所占存儲(chǔ)單元的字節(jié)數(shù)。例如,用DB定義的變量類型屬性為BYTE(字節(jié)),用DW定義的變量類型屬性為WORD(字),用DD定義的變量類型屬性DWORD(雙字)等。
(4)標(biāo)號(hào)需要時(shí)可給指令的地址取名字,標(biāo)號(hào)就是指令地址的名字,也稱指令的符號(hào)地址。標(biāo)號(hào)定義在指令的前面,用冒號(hào)作為分隔符。標(biāo)號(hào)只能定義在代碼段中,它代表其后第一條指令的第一個(gè)字節(jié)的存儲(chǔ)單元地址,用于說明指令在存儲(chǔ)器中的存儲(chǔ)位置,可作為轉(zhuǎn)移類指令的直接操作數(shù)(轉(zhuǎn)移地址)。例如,在下列指令序列中的L就是標(biāo)號(hào),它是JNZ指令的直接操作數(shù)(轉(zhuǎn)移地址)。
MOVCX,2L:DECCXJNZL標(biāo)號(hào)有如下的屬性:①段基值:即標(biāo)號(hào)后面第一條指令所在代碼段的段基值;②偏移地址:即標(biāo)號(hào)后面第一條指令首字節(jié)的段內(nèi)偏移地址;③類型:也稱距離屬性,即標(biāo)號(hào)與引用該標(biāo)號(hào)的指令之間允許距離的遠(yuǎn)、近。近標(biāo)號(hào)的類型屬性為NEAR(近),這樣的標(biāo)號(hào)只能被本段的指令引用;遠(yuǎn)標(biāo)號(hào)的類型屬性為FAR(遠(yuǎn)),這樣的標(biāo)號(hào)可被任何段的指令引用。(5)偏移地址計(jì)數(shù)器$匯編程序在對(duì)源程序進(jìn)行匯編的過程中,用偏移地址計(jì)數(shù)器$來保存當(dāng)前正在匯編的指令的偏移地址或偽指令語句中變量的偏移地址。用戶可將$用于自己編寫的源程序中。在每個(gè)段開始匯編時(shí),匯編程序都將$清為0。以后,每處理一條指令或一個(gè)變量,$就增加一個(gè)值,此值為該指令或該變量所占的字節(jié)數(shù)??梢?,$的內(nèi)容就是當(dāng)前指令或變量的偏移地址。在偽指令中,$代表其所在地的偏移地址。例如,下列語句中的第一個(gè)$+4的偏移地址為A+4,第二個(gè)$+4的偏移地址為A+10。
ADW1,2,$+4,3,4,$+4如果A的偏移地址是0074H,則匯編后,該語句中第一個(gè)$+4=(A+4)+4=(0074H+4)+4=007CH,第二個(gè)$+4=(A+10)+4=(0074H+0AH)+4=0082H。于是,從A開始的字?jǐn)?shù)據(jù)將依次為:
0001H,0002H,007CH,0003H,0004H,0082H在機(jī)器指令中,$無論出現(xiàn)在指令的任何位置,都代表本條指令第一個(gè)字節(jié)的偏移地址。例如,“JZ$+6”的轉(zhuǎn)向地址是該指令的首地址加上6,$+6還必須是另一條指令的首地址。例如,在下述指令序列中:
DECCXJZ$+5MOVAX,2LAB:...因?yàn)?代表JZ指令的首字節(jié)地址,而JZ指令占2個(gè)字節(jié),相繼的MOV指令占3個(gè)字節(jié),所以,在發(fā)生轉(zhuǎn)移時(shí),JZ指令會(huì)將程序轉(zhuǎn)向LAB標(biāo)號(hào)處的指令,且標(biāo)號(hào)LAB可省。5.2.4偽指令語句
偽指令語句又稱作指示性(directive)語句,它沒有對(duì)應(yīng)的機(jī)器指令,在匯編過程中不形成機(jī)器代碼,這是偽指令語句與指令語句的本質(zhì)區(qū)別。偽指令語句不要求CPU執(zhí)行,而是讓匯編程序在匯編過程中完成特定的功能,它在很大程度上決定了匯編語言的性質(zhì)及其功能。偽指令語句的格式如圖5.3所示。圖5.3偽指令語句格式從圖5.3可以看出,偽指令語句與指令語句很相似,不同之處在于偽指令語句開始是一個(gè)可選的名字字段,它也是一個(gè)標(biāo)識(shí)符,相當(dāng)于指令語句的標(biāo)號(hào)。但是名字后面不允許帶冒號(hào)“:”,而指令語句的標(biāo)號(hào)后面必須帶冒號(hào),這是兩種語句形式上最明顯的區(qū)別。
1.符號(hào)定義語句匯編語言中所有的變量名、標(biāo)號(hào)名、過程名、記錄名、指令助記符、寄存器名等統(tǒng)稱為“符號(hào)”,這些符號(hào)可由符號(hào)定義語句來定義,也可以定義為其他名字及新的類型屬性。符號(hào)定義語句有三種,即EQU語句、=語句和PURGE語句。(1)EQU語句EQU語句給符號(hào)定義一個(gè)值,或定義為別的符號(hào),甚至可定義為一條可執(zhí)行的指令、表達(dá)式的值等。EQU語句的格式為:符號(hào)名EQU表達(dá)式例如:
PORT1EQU78PORT2EQUPORT1+2COUNTEREQUCXCBDEQUDAA這里,COUNTER和CBD分別被定義為寄存器CX和指令助記符DAA。經(jīng)EQU語句定義的符號(hào)不允許在同一個(gè)程序模塊中重新定義。另外,EQU語句只作為符號(hào)定義用,它不產(chǎn)生任何目標(biāo)代碼,也不占用存儲(chǔ)單元。(2)=語句=語句與EQU語句功能類似,但此語句允許對(duì)已定義的符號(hào)重新定義,因而更靈活方便。其語句格式如下:
符號(hào)名=表達(dá)式例如:
A=6A=9A=A+2
(3)PURGE(取消語句)PURGE語句的格式為:
PURGE符號(hào)名1[,符號(hào)名2[,…]]PURGE語句取消被EQU語句定義的符號(hào)名,然后即可用EQU語句再對(duì)該符號(hào)名重新定義。例如,可用PURGE語句實(shí)現(xiàn)如下操作:
AEQU7PURGEA;取消A的定義
AEQU8;重新定義2.數(shù)據(jù)定義語句
數(shù)據(jù)定義語句為一個(gè)數(shù)據(jù)項(xiàng)分配存儲(chǔ)單元,用一個(gè)符號(hào)與該存儲(chǔ)單元相聯(lián)系,并可以為該數(shù)據(jù)項(xiàng)提供一個(gè)任選的初始值。數(shù)據(jù)定義語句DB,DW,DD,DQ,DT可分別用來定義字節(jié)、字、雙字、四字、十字節(jié)變量,并可用復(fù)制操作符DUP來復(fù)制數(shù)據(jù)項(xiàng)。例如:
FIRSTDB27HSECONDDD12345678HTHIRDDW?,0A2HFORTHDB2DUP(2DUP(1,2),3)其中問號(hào)“?”表示相應(yīng)存儲(chǔ)單元沒有初始值。上面定義的變量在存儲(chǔ)器中的存放格式如圖5.4所示。
圖5.4數(shù)據(jù)變量存儲(chǔ)格式圖5.5字符串變量存儲(chǔ)格式
數(shù)據(jù)項(xiàng)也可以寫成字符串形式,但只能用DB和DW來定義,且DW語句定義的串只允許包含兩個(gè)字符。例如:
ONEDB’AB’TWODW’AB’,’CD’THREEDB’HELLO’
上述變量的存放格式如圖5.5所示,注意DB’AB’與DW’AB’的存放格式不同??梢杂肈W語句把變量或標(biāo)號(hào)的偏移地址存入存儲(chǔ)器。也可以用DD語句把變量或標(biāo)號(hào)的段基值和偏移地址都存入存儲(chǔ)器,此時(shí)低位字存偏移地址,高位字存段基值。例如:
VARDB34HLABL:MOVAL,04H…PRVDDVAR
PRLDWLABL其存放格式如圖5.6所示。
圖5.6地址變量的存放格式【例5.1】執(zhí)行下列程序后,CX=
。
DATASEGMENTADW1,2,3,4,5BDW5DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:
MOVAX,DATAMOVDS,AXLEABX,AADDBX,BMOVCX,[BX]
MOVAH,4CHINT21HCODEENDSENDSTART在例5.1所示程序中,當(dāng)執(zhí)行指令“LEABX,A”時(shí),將A相對(duì)數(shù)據(jù)段首址的偏移量0送入BX寄存器;執(zhí)行指令“ADDBX,B”后,BX=5;再執(zhí)行指令“MOVCX,[BX]”時(shí),由于源操作數(shù)是寄存器間接尋址方式且該指令為字傳送指令,因此應(yīng)將相對(duì)數(shù)據(jù)段首址偏移量為5的字單元內(nèi)容0400送入CX寄存器。上述程序執(zhí)行完成后,CX=0400。3.段定義語句段定義語句指示匯編程序如何按段組織程序和使用存儲(chǔ)器,主要有SEGMENT、ENDS、ASSUME、ORG等。下面分別予以介紹。1)段開始語句SEGMENT和段結(jié)束語句ENDS一個(gè)邏輯段的定義格式如下:
段名SEGMENT[定位類型][組合類型]’類別’┇段名ENDS整個(gè)邏輯段以SEGMENT語句開始,以ENDS語句結(jié)束。其中段名是程序員指定的,SEGMENT左邊的段名與ENDS左邊的段名必須相同。定位類型、組合類型和類別是賦給段名的屬性,且都可以省略,若不省略則各項(xiàng)順序不能錯(cuò)。(1)定位類型表示此段的起始地址邊界要求,有PAGE,PARA,WORD和BYTE四種方式,默認(rèn)值為PARA。它們的邊界要求如下:PAGEXXXXXXXX
XXXX00000000PARAXXXXXXXX
XXXX
XXXX0000WORDXXXXXXXX
XXXX
XXXXXXX0BYTEXXXXXXXX
XXXX
XXXXXXXX
即分別要求地址的低8位為0(頁(yè)邊界)、低4位為0(節(jié)邊界)、最低位為0(字邊界)及地址任意(字節(jié)邊界)。(2)組合類型告訴連接程序本段與其他段的關(guān)系。有NONE、PUBLIC、COMMON、STACK、MEMORY和“AT表達(dá)式”共6種,分別介紹如下:①NONE表示本段與其他段邏輯上不發(fā)生關(guān)系,每段都有自己的段基地址。這是默認(rèn)的組合類型。②
PUBLIC告訴連接程序首先把本段與用PUBLIC說明的同名同類別的其他段連接成一個(gè)段,所有這些段用一個(gè)相同的段基地址。③COMMON表示本段與同名同類別的其他段共用同一段基地址,即同名同類段相重疊,段的長(zhǎng)度是其中最長(zhǎng)段的長(zhǎng)度。
④STACK表示本段是堆棧段,連接方式同PUBLIC。被連接程序中必須至少有一個(gè)堆棧段,有多個(gè)堆棧段時(shí)采用覆蓋方式進(jìn)行組合。連接后的段基地址在SS寄存器中。⑤MEMORY表示該段在連接時(shí)被放在所有段的最后(最高地址)。若有幾個(gè)MEMORY組合類型的段,匯編程序認(rèn)為所遇到的第一個(gè)為MEMORY,其余為COMMON型。⑥“AT表達(dá)式”告訴連接程序把本段裝在表達(dá)式的值所指定的段基地址處。例如:“AT1234H”表示該段的段基地址為12340H。(3)類別是用單引號(hào)括起來的字符串,可以是長(zhǎng)度不超過40個(gè)字符的串。連接程序只使相同類別的段發(fā)生關(guān)連。典型的類別如’STACK’、’CODE’、’DATA’等。
2)段分配語句ASSUME段分配語句ASSUME用來告訴匯編程序當(dāng)前哪4個(gè)段分別被定義為代碼段、數(shù)據(jù)段、堆棧段和附加段,以便對(duì)使用變量或標(biāo)號(hào)的指令生成正確的目標(biāo)代碼。其格式是:ASSUME段寄存器:段名[,段寄存器:段名,…]注意,使用ASSUME語句只是告訴匯編程序有關(guān)段寄存器將被設(shè)定為哪個(gè)段的段基值,而段基值的真正設(shè)定必須通過給段寄存器賦值的指令語句來完成。例如:CODESEGMENT
ASSUMEDS:DATA,ES:DATA,CS:CODE,SS:STACKMOVAX,DATAMOVDS,AXMOVES,AXMOVAX,STACKMOVSS,AX┇段寄存器CS的值是由系統(tǒng)設(shè)置的,因此程序中不必進(jìn)行賦值。3)定位語句ORG定位語句ORG的格式為:
ORG表達(dá)式用來指出其后的程序塊或數(shù)據(jù)塊從表達(dá)式之值作為存放的起始地址(偏移地址)。若沒有ORG語句則從本段的起始地址開始存放。
4.過程定義語句過程是程序的一部分,可被主程序調(diào)用。每次可調(diào)用一個(gè)過程,當(dāng)過程中的指令執(zhí)行完后,控制返回調(diào)用它的地方。利用過程定義語句可以把程序分成若干獨(dú)立的程序模塊,便于理解、調(diào)試和修改。過程調(diào)用對(duì)模塊化程序設(shè)計(jì)是很方便的。8086系統(tǒng)中過程調(diào)用和返回指令是CALL和RET,可分為段內(nèi)和段間操作兩種情況。段間操作把過程返回地址的段基值和偏移地址都?jí)簵?通過執(zhí)行CALL指令實(shí)現(xiàn))或退棧(通過執(zhí)行RET指令實(shí)現(xiàn)),而段內(nèi)操作則只把偏移地址壓?;蛲藯?。過程定義語句的格式為:
過程名PROC[NEAR/FAR]┇過程名ENDP其中,過程名是一個(gè)標(biāo)識(shí)符,是給被定義過程取的名字。過程名像標(biāo)號(hào)一樣,有3重屬性:段基值、偏移地址和距離屬性(NEAR或FAR)。NEAR或FAR指明過程的距離屬性。NEAR過程只允許段內(nèi)調(diào)用,F(xiàn)AR過程則允許段間調(diào)用。默認(rèn)時(shí)為NEAR過程。過程內(nèi)部至少要設(shè)置一條返回指令RET,以作為過程的出口。允許一個(gè)過程中有多條RET指令,而且可以出現(xiàn)在過程的任何位置上。5.其他偽指令語句①模塊開始偽指令語句NAME指明程序模塊的開始,并指出模塊名,其格式為:
NAME模塊名該語句在一個(gè)程序中不是必需的,可以不寫。②模塊結(jié)束偽指令語句END標(biāo)志整個(gè)源程序的結(jié)束,匯編程序匯編到該語句時(shí)結(jié)束。其格式為:END[標(biāo)號(hào)]其中標(biāo)號(hào)是程序中第一個(gè)指令性語句(或第一條指令)的符號(hào)地址。注意,當(dāng)程序由多個(gè)模塊組成時(shí),只需在主程序模塊的結(jié)束語句(END語句)中寫出該標(biāo)號(hào),其他子程序模塊的結(jié)束語句中則可以省略。③對(duì)準(zhǔn)偽指令語句EVEN要求匯編程序?qū)⑾乱徽Z句所指向的地址調(diào)整為偶地址,使用時(shí)直接用偽指令名EVEN就可以了。例如,下述EVEN偽指令將把字?jǐn)?shù)組ARY調(diào)整到偶地址開始處。
EVENARYDW100DUP(?)
又如,下述偽指令序列:
ORG1000HADB12H,34H,56HEVENBDB78H其中,ORG1000H將A的偏移地址指定為1000H,從A開始存放3個(gè)字節(jié)變量,占用地址1000H、1001H和1002H,B的偏移地址部分本應(yīng)是1003H,但EVEN偽指令會(huì)將其調(diào)整為偶數(shù)地址1004H。說明:由于80x86系統(tǒng)在存儲(chǔ)器結(jié)構(gòu)上所采用的設(shè)計(jì)技術(shù),使得對(duì)于8086這樣的16位CPU,如果從偶地址開始訪問一個(gè)字,可以在一個(gè)總線周期內(nèi)完成;但如果從奇地址開始訪問一個(gè)字,則由于對(duì)兩個(gè)字節(jié)必須分別訪問,所以要用兩個(gè)總線周期才能完成。對(duì)于80386以上的32位CPU,如果從雙字邊界(地址為4的倍數(shù))開始訪問一個(gè)雙字?jǐn)?shù)據(jù),可以在一個(gè)總線周期內(nèi)完成,否則需用多個(gè)總線周期。在安排存儲(chǔ)器數(shù)據(jù)時(shí),為了提高程序的運(yùn)行速度,最好將字型數(shù)據(jù)從字邊界(偶地址)開始存放,雙字?jǐn)?shù)據(jù)從雙字邊界開始存放。對(duì)準(zhǔn)偽指令EVEN就是專門為實(shí)現(xiàn)這樣的功能而設(shè)置的。④默認(rèn)基數(shù)偽指令語句RADIX,其作用在5.2.2節(jié)講述數(shù)的表示時(shí)已有說明,其格式為:
RADIX表達(dá)式⑤LABEL偽指令語句可用來給已定義的變量或標(biāo)號(hào)取一個(gè)別名,并重新定義它的屬性,以便于引用。其格式為:變量名/標(biāo)號(hào)名LABEL類型對(duì)于變量名,類型可為BYTE、WORD、DWORD、QWORD、TBYTE等。對(duì)于標(biāo)號(hào)名,類型可為NEAR和FAR。例如:
VARBLABELBYTE;給下面的變量VARW取了一個(gè)新名字
VARB,并賦予另外的屬性BYTE。
VARWDW4142H,4344H
PTRFLABELFAR;給下面的標(biāo)號(hào)PTRN取了一個(gè)新名字
PTRF,并賦予另外的屬性FAR。
PTRN:MOVAX,[DI]注意,LABEL偽指令的功能與前述THIS偽指令類似,兩者均不為所在語句的符號(hào)分配內(nèi)存單元,區(qū)別是使用LABEL可以直接定義,而使用THIS偽指令則需要與EQU或“=”連用。⑥COMMENT偽指令語句用于書寫大塊注釋,其格式為:
COMMENT定界符注釋定界符其中定界符是自定義的任何非空字符。例如:
COMMENT/
注釋文
/⑦TITLE偽指令語句為程序指定一個(gè)不超過60個(gè)字符的標(biāo)題,以后的列表文件會(huì)在每頁(yè)的第一行打印這個(gè)標(biāo)題。SUBTTL偽指令語句為程序指定一個(gè)小標(biāo)題,打印在每一頁(yè)的標(biāo)題之后。格式如下:
TITLE標(biāo)題
SUBTTL小標(biāo)題⑧PAGE偽指令語句指定列表文件每頁(yè)的行數(shù)(10~255)和列數(shù)(60~132),默認(rèn)值是每頁(yè)66行80列。其格式如下:
PAGE行數(shù),列數(shù)⑨模塊連接偽指令語句主要解決多模塊的連接問題。一個(gè)大的程序往往要分模塊來完成編碼、調(diào)試的工作,然后再整體連接和調(diào)試。它們的格式如下:
PUBLIC符號(hào)名[,符號(hào)名,…]
EXTERN符號(hào)名:類型[,符號(hào)名:類型,…]
INCLUDE模塊名組名GROUP段名[,段名,…]其中符號(hào)名可以是變量名、標(biāo)號(hào)、過程名、常量名等。
以變量名為例,一個(gè)程序模塊中用PUBLIC偽指令定義的變量可由其他模塊引用,否則不能被其他模塊引用;在一個(gè)模塊中引用其他模塊中定義的變量必須在本模塊用EXTERN偽指令進(jìn)行說明,而且所引用的變量必須是在其他模塊中用PUBLIC偽指令定義的。換句話說,如果要在“使用模塊”中訪問其他模塊中定義的變量,除要求該變量在其“定義模塊”中定義為PUBLIC類型外,還需在“使用模塊”中用EXTERN偽指令說明該變量,以通知匯編器該變量是在其他模塊中定義的。例如,一個(gè)應(yīng)用程序包括A、B、C三個(gè)程序模塊,而VAR是定義在模塊A數(shù)據(jù)段中的一個(gè)變量,其定義格式如下:
PUBLICVAR由于VAR被定義為PUBLIC,所以在模塊B或C中也可以訪問這個(gè)變量,但必須在模塊B或C中用EXTERN偽指令說明這個(gè)變量。其格式如下所示:
EXTERNVAR:Type注意,匯編器并不能檢查變量類型Type和原定義是否相同,這需要編程者自己維護(hù)。INCLUDE偽指令告訴匯編程序把另外的模塊插入本模塊該偽指令處一起匯編,被插入的模塊可以是不完整的。GROUP偽指令告訴匯編程序把其后指定的所有段組合在一個(gè)64K的段中,并賦予一個(gè)名字——組名。組名與段名不可相同。5.2.5宏指令
在匯編語言源程序中,有的程序段可能要多次使用,為了使在源程序中不重復(fù)書寫這一程序段,可以用一條宏指令來代替,在匯編時(shí)由匯編程序進(jìn)行宏擴(kuò)展而產(chǎn)生所需要的代碼。1.宏定義語句宏指令的使用過程就是宏定義、宏調(diào)用和宏擴(kuò)展的三個(gè)過程,下面分別予以說明。1)宏定義宏定義由偽指令MACRO和ENDM來定義,其語句格式為:
宏指令名
MACRO[形式參數(shù),形式參數(shù),…]┇宏體
ENDM其中宏指令名是一個(gè)標(biāo)識(shí)符,是程序員給該宏指令取的名字。MACRO是宏定義的開始符,ENDM是宏定義的結(jié)束符,兩者必須成對(duì)出現(xiàn)。注意,ENDM左邊不需加宏指令名。MACRO和ENDM之間的指令序列稱為宏定義體(簡(jiǎn)稱宏體),即要用宏指令來代替的程序段。宏指令具有接受參數(shù)的能力,宏體中使用的形式參數(shù)必須在MACRO語句中出現(xiàn)。形式參數(shù)可以沒有,也可以有多個(gè)。當(dāng)有兩個(gè)以上參數(shù)時(shí),需用逗號(hào)隔開。在宏指令被調(diào)用時(shí),這些參數(shù)將被給出的一些名字或數(shù)值所替代,這里的名字或數(shù)值稱為“實(shí)參數(shù)”。實(shí)際上,形式參數(shù)只是指出了在何處以及如何使用實(shí)參數(shù)的方法。形式參數(shù)的使用使宏指令在參數(shù)傳遞上更加靈活。例如,移位宏指令SHIFT可定義如下:
SHIFTMACROXMOVCL,XSALAL,CLENDM其中SHIFT為宏指令名,X為形式參數(shù)。2)宏調(diào)用經(jīng)過宏定義后,在源程序中的任何位置都可以直接使用宏指令名來實(shí)現(xiàn)宏指令的引用,稱為宏調(diào)用。它要求匯編程序把宏定義體(程序段)的目標(biāo)代碼復(fù)制到調(diào)用點(diǎn)。如果宏定義是帶參數(shù)的,就用宏調(diào)用時(shí)的實(shí)參數(shù)替代形式參數(shù),其位置一一對(duì)應(yīng)。宏調(diào)用的格式為:
宏指令名[實(shí)參數(shù),實(shí)參數(shù),…]其中實(shí)參數(shù)將一一對(duì)應(yīng)地替代宏定義體中的形式參數(shù)。同樣,當(dāng)有兩個(gè)以上參數(shù)時(shí),需用逗號(hào)隔開。注意,并不要求形式參數(shù)個(gè)數(shù)與實(shí)在參數(shù)一樣多。若實(shí)在參數(shù)多于形式參數(shù),多余的將被忽略;若實(shí)在參數(shù)比形式參數(shù)少,則多余的形式參數(shù)變?yōu)榭?NULL)。例如,調(diào)用前面定義的宏指令SHIFT時(shí),可寫為:
SHIFT6;用參數(shù)6替代宏體中的參數(shù)X,從而實(shí)現(xiàn)宏調(diào)用。
3)宏擴(kuò)展在匯編宏指令時(shí),宏匯編程序?qū)⒑牦w中的指令插入到源程序宏指令所在的位置上,并用實(shí)參數(shù)代替形式參數(shù),同時(shí)在插入的每一條指令前加一個(gè)“+”號(hào),這個(gè)過程稱為宏擴(kuò)展。例如,上例的宏擴(kuò)展為:
+MOVCL,6+SALAL,CL又如,假設(shè)有下列的宏定義:
SHIFTMACROX,YMOVCL,XMOVY,CLENDM那么宏調(diào)用“SHIFT4,AL”將被擴(kuò)展為:
+MOVCL,4+SALAL,CL形式參數(shù)不僅可以出現(xiàn)在指令的操作數(shù)部分,而且可以出現(xiàn)在指令操作助記符的某一部分,但這時(shí)需在相應(yīng)形式參數(shù)前加宏操作符&,宏擴(kuò)展時(shí)將把&前后兩個(gè)符號(hào)合并成一個(gè)符號(hào)。例如,對(duì)于下面的宏定義:
SHIFTMACROX,Y,ZMOVCL,XS&ZY,CLENDM則下面兩個(gè)宏調(diào)用
SHIFT4,AL,ALSHIFT6,BX,AR將被宏擴(kuò)展為如下的指令序列:+MOVCL,4
+SALAL,CL
+MOVCL,6
+SARBX,CL實(shí)際上,這個(gè)例子中的宏指令SHIFT帶上合適的參數(shù)可以對(duì)任一個(gè)寄存器進(jìn)行任意的移位操作,而且可以移位任意指定的位數(shù)。2.局部符號(hào)定義語句
局部符號(hào)定義語句用來定義僅在宏定義體內(nèi)引用的符號(hào),這樣可以防止在宏擴(kuò)展時(shí)引起符號(hào)重復(fù)定義的錯(cuò)誤。其格式為:
LOCAL符號(hào)[,符號(hào)…]
匯編時(shí),對(duì)LOCAL偽指令說明的符號(hào)每宏擴(kuò)展一次便建立一個(gè)惟一的符號(hào),以保證匯編生成名字的惟一性。需要注意的是,LOCAL語句必須是MACRO偽指令后的第一個(gè)語句,且與MACRO之間不能有注釋等其他內(nèi)容。3.注銷宏定義語句
該語句用來取消一個(gè)宏指令定義,然后就可以重新定義。其格式為:
PURGE宏指令名[,宏指令名…]由以上對(duì)宏指令的介紹可以看出,宏指令與子程序有某些相似之處,但兩者也有區(qū)別,表現(xiàn)在以下幾個(gè)方面:①在處理的時(shí)間上,宏指令是在匯編時(shí)進(jìn)行宏擴(kuò)展,而子程序是在執(zhí)行時(shí)由CPU處理的。②在目標(biāo)代碼的長(zhǎng)度上,由于采用宏指令方式時(shí)的宏擴(kuò)展是將宏定義體原原本本地插入到宏指令調(diào)用處,所以它并不縮短目標(biāo)代碼的長(zhǎng)度,而且宏調(diào)用的次數(shù)越多,目標(biāo)代碼長(zhǎng)度越長(zhǎng),所占內(nèi)存空間也就越大;采用子程序方式時(shí),若在一個(gè)源程序中多次調(diào)用同一個(gè)子程序,則在目標(biāo)程序的主程序中只有調(diào)用指令的目標(biāo)代碼,子程序的目標(biāo)代碼在整個(gè)目標(biāo)程序中只有一段,所以采用子程序方式可以縮短目標(biāo)代碼的長(zhǎng)度。③子程序每次執(zhí)行都要進(jìn)行返回地址的保護(hù)和恢復(fù),因此延長(zhǎng)了執(zhí)行時(shí)間,而宏指令方式不會(huì)增加這樣的時(shí)間開銷。④兩者在傳遞參數(shù)的方式上也有所不同。宏指令是通過形式參數(shù)和實(shí)參數(shù)的方式來傳遞參數(shù)的,而子程序方式則是通過寄存器、堆?;騾?shù)表的方式來進(jìn)行參數(shù)的傳遞??梢愿鶕?jù)使用需要在子程序方式和宏指令方式之間進(jìn)行選擇。一般來說,當(dāng)要代替的程序段不很長(zhǎng),執(zhí)行速度是主要矛盾時(shí),通常采用宏指令方式;當(dāng)要代替的程序段較長(zhǎng),額外操作(返回地址的保存、恢復(fù)等)所增加的時(shí)間已不明顯,而節(jié)省存儲(chǔ)空間是主要矛盾時(shí),通常宜采用子程序方式。5.2.6簡(jiǎn)化段定義
MASM5.0以上版本的宏匯編程序提供了簡(jiǎn)化段來定義偽指令,Borland公司的TASM也支持簡(jiǎn)化段。簡(jiǎn)化段偽指令根據(jù)默認(rèn)值來提供段的相應(yīng)屬性,采用的段名和屬性符合Microsoft高級(jí)語言的約定。簡(jiǎn)化段使編寫匯編語言程序更為簡(jiǎn)單、不易出錯(cuò),且更容易與高級(jí)語言相連接。教材中表5-4給出了簡(jiǎn)化段偽指令的名稱、格式及操作描述。表5-4中的偽指令MODEL指定的各種存儲(chǔ)模式及其使用環(huán)境如表5-5所示。下面給出一個(gè)使用簡(jiǎn)化段定義的程序例子。
.MODELSmall;定義存儲(chǔ)模式為Small.DATA;數(shù)據(jù)段
STRINGDB’HelloWorld!’,0AH,0DH,’$’.STACK100H;100H字節(jié)的堆棧段
.CODE;代碼段
ASSUMECS:_TEXT,DS:_DATA,SS:STACKSTARTPROCFARMOVAX,_DATAMOVDS,AXMOVDX,OFFSETSTRINGMOVAH,9INT21HMOVAH,4CHINT21HSTARTENDPENDSTART
5.3ROMBIOS中斷調(diào)用和DOS系統(tǒng)功能調(diào)用
80x86微機(jī)系統(tǒng)通過ROMBIOS和DOS提供了豐富的系統(tǒng)服務(wù)子程序,用戶可以很容易地調(diào)用這些系統(tǒng)服務(wù)軟件,給程序設(shè)計(jì)帶來很大方便。5.3.1ROMBIOS中斷調(diào)用80x86微型計(jì)算機(jī)的系統(tǒng)板中裝有ROM,其中從地址0FE00H開始的8KB為ROMBIOS。駐留在ROM中的BIOS例行程序提供了系統(tǒng)加電自檢、引導(dǎo)裝入以及對(duì)主要I/O接口控制等功能。對(duì)I/O接口的控制,主要是指對(duì)鍵盤、磁帶、磁盤、顯示器、打印機(jī)、異步串行通信接口等的控制,此外BIOS還提供了最基本的系統(tǒng)硬件與軟件間的接口。ROMBIOS為程序員提供了很大的方便。程序員可以不必了解硬件的詳細(xì)接口特性,而是通過直接調(diào)用BIOS中的例行程序來完成對(duì)主要I/O設(shè)備的控制管理。BIOS由許多功能模塊組成,每個(gè)功能模塊的入口地址都在中斷向量表中。通過軟件中斷指令“INTn”可以直接調(diào)用這些功能模塊。CPU響應(yīng)中斷后,把控制權(quán)交給指定的BIOS功能模塊,由它提供相應(yīng)服務(wù)。BIOS中斷調(diào)用的入口參數(shù)和出口參數(shù)均采用寄存器傳送。若一個(gè)BIOS子程序能完成多種功能,則用功能號(hào)來加以區(qū)分,并將相應(yīng)的功能號(hào)預(yù)置于AH寄存器中。BIOS中斷調(diào)用的基本方法如下:
(1)將所要調(diào)用功能的功能號(hào)送入AH寄存器;(2)根據(jù)所調(diào)用功能的規(guī)定設(shè)置入口參數(shù);
(3)執(zhí)行“INT中斷號(hào)”指令,進(jìn)入相應(yīng)的服務(wù)子程序;(4)中斷服務(wù)子程序執(zhí)行完畢后,可按規(guī)定取得出口參數(shù)?!纠?.2】利用“INT1AH”的1號(hào)功能將時(shí)間計(jì)數(shù)器的當(dāng)前值設(shè)置為零。
MOVAH,1;設(shè)置功能號(hào)
MOVCX,0;設(shè)置入口參數(shù)
MOVDX,0;
INT1AH;BIOS中斷調(diào)用
5.3.2DOS系統(tǒng)功能調(diào)用BIOS常駐在系統(tǒng)板的ROM中,獨(dú)立于任何操作系統(tǒng)。
DOS則以BIOS為基礎(chǔ),為用戶提供了一組可以直接使用的服務(wù)程序。這組服務(wù)程序共用21H號(hào)中斷入口,也以功能號(hào)來區(qū)分不同的功能模塊。這一組服務(wù)程序就稱為DOS系統(tǒng)功能調(diào)用。DOS系統(tǒng)功能調(diào)用的方法與BIOS中斷調(diào)用類似,只是中斷號(hào)固定為21H?!纠?.3】利用6號(hào)DOS系統(tǒng)功能調(diào)用在屏幕上輸出字符“$”。
MOVAH,6;設(shè)置功能號(hào)為6MOVDL,’$’;設(shè)置入口參數(shù)
INT21H;DOS系統(tǒng)功能調(diào)用5.4匯編語言程序的上機(jī)調(diào)試1.建立源文件上機(jī)開始,首先要使用編輯程序完成源程序的建立和修改工作。啟動(dòng)EDIT的常用命令格式如下:
EDIT
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 手挖掘機(jī)買賣合同常用
- 房屋租賃權(quán)質(zhì)押合同
- 社區(qū)綠地資源開發(fā)與保護(hù)合同書
- 2025年高校大學(xué)生朋輩心理輔導(dǎo)技能大賽考試題庫(kù)-下(多選、判斷題)
- 《信息技術(shù)原理》課件
- 《財(cái)務(wù)核算管理》課件
- 2024年家政服務(wù)業(yè)職業(yè)技能大賽母嬰護(hù)理員賽項(xiàng)理論試題庫(kù)(1000題)
- 學(xué)校安全教育班會(huì)課件
- 廣告設(shè)計(jì)師廣告策劃題目試題及答案
- 《管理效能取決于領(lǐng)導(dǎo)力:課件中的執(zhí)行力解析》
- 下肢動(dòng)脈疾病PAD課件
- 2025浙江溫州市公用事業(yè)發(fā)展集團(tuán)有限公司招聘54人(第一批)筆試參考題庫(kù)附帶答案詳解
- 《超重問題與健康對(duì)策》課件
- ktv陪酒合同協(xié)議
- 上海嘉定區(qū)2025年公開招聘農(nóng)村(村務(wù))工作者筆試題帶答案分析
- 皮膚科臨床診療規(guī)范2020版
- 陜西、山西省天一大聯(lián)考2024-2025學(xué)年高中畢業(yè)班階段性測(cè)試(七)歷史試題及答案
- 保密警示教育典型泄密案例教育學(xué)習(xí)
- 高中數(shù)學(xué)不等式教學(xué)中的認(rèn)知障礙診斷與干預(yù)機(jī)制研究
- 《大學(xué)生職業(yè)生涯規(guī)劃與就業(yè)指導(dǎo)(實(shí)踐版)》全套教學(xué)課件
- 建筑企業(yè)財(cái)務(wù)管理的風(fēng)險(xiǎn)控制與應(yīng)對(duì)策略
評(píng)論
0/150
提交評(píng)論