微機(jī)原理-匯編語言程序設(shè)計(jì)_第1頁(yè)
微機(jī)原理-匯編語言程序設(shè)計(jì)_第2頁(yè)
微機(jī)原理-匯編語言程序設(shè)計(jì)_第3頁(yè)
微機(jī)原理-匯編語言程序設(shè)計(jì)_第4頁(yè)
微機(jī)原理-匯編語言程序設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩265頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第6章匯編語言程序設(shè)計(jì)6.1匯編語言語法6.2匯編語言程序設(shè)計(jì)6.3匯編程序及上機(jī)過程

6.4DOS及BIOS功能調(diào)用

6.5任務(wù)切換與混合語言編程6.1匯編語言語法6.1.1計(jì)算機(jī)程序設(shè)計(jì)語言的演變1.機(jī)器語言(MachineLanguage)

任何計(jì)算機(jī)實(shí)際上只能直接識(shí)別設(shè)計(jì)微處理器時(shí)所規(guī)定好的,一整套用“0”、“1”數(shù)字代碼表示的機(jī)器指令。這些機(jī)器指令的全體是指令系統(tǒng)。不同類型的CPU,其機(jī)器語言必然是不同的。這種直接用機(jī)器指令來編制計(jì)算機(jī)程序的方法就稱為機(jī)器語言程序設(shè)計(jì)。教學(xué)用的單板計(jì)算機(jī)一般都直接采用機(jī)器語言編程。這種直接用機(jī)器語言編程的方法難度大,閱讀、查錯(cuò)和修改程序也很不方便。通常,只有當(dāng)編程者對(duì)CPU指令系統(tǒng)比較熟悉,編寫的程序較短時(shí),才有可能直接用機(jī)器語言來寫。人們?yōu)榱藬[脫編程中這種原始而低級(jí)的狀態(tài),就設(shè)法采用一組字母、數(shù)字或字符來代替機(jī)器指令,這樣就產(chǎn)生了匯編語言的概念和方法。2.匯編語言(AssemblyLanguage)和機(jī)器語言相比,使用匯編語言來編寫程序可以用助記符來表示指令的操作碼和操作數(shù),也可以用標(biāo)號(hào)和符號(hào)來代替地址、常量和變量。但由于不同CPU的指令系統(tǒng)的指令編碼不同,因此與之相應(yīng)的匯編語言亦不相同。由于這種符號(hào)化的語言使用了用英文字母縮寫表示的助記符,便于識(shí)別與記憶。另外,匯編程序還引入了新的匯編指令——偽指令和宏指令,使得采用匯編語言進(jìn)行程序設(shè)計(jì)更為方便靈活。圖6.1匯編程序的“翻譯”作用3.高級(jí)語言(Highlevellanguage)低級(jí)語言編程方式阻礙了計(jì)算機(jī)在國(guó)民經(jīng)濟(jì)及日常生活中的推廣應(yīng)用。隨著計(jì)算機(jī)科學(xué)的發(fā)展,軟件、硬件技術(shù)在相輔相成、相互支持中不斷改進(jìn)與完善,逐步創(chuàng)造出許多適用于不同應(yīng)用場(chǎng)合的計(jì)算機(jī)高級(jí)語言,如BASIC、FORTRAN、COBOL、PASCAL、FORTH、C語言等。這些高級(jí)的程序設(shè)計(jì)語言,使用了更接近于人們的自然語言(英語)和習(xí)慣的教學(xué)語言來描述算法的執(zhí)行過程,從而使編寫的程序更加直觀和簡(jiǎn)練。這些高級(jí)語言通常都包含有各種函數(shù)計(jì)算、字符串處理、數(shù)據(jù)I/O等功能。所以程序的編寫、閱讀和修改變得相當(dāng)容易掌握和使用。高級(jí)語言無論是面向問題或面向過程,一般總是獨(dú)立于具體機(jī)器的。程序員可不必了解機(jī)器的指令系統(tǒng)和內(nèi)部的具體結(jié)構(gòu),而把精力集中在正確掌握語言的語法規(guī)則和算法的程序?qū)崿F(xiàn)上。同樣,高級(jí)語言也必須借助于更強(qiáng)有力的翻譯系統(tǒng)——編譯程序(Compiler)才能將源程序轉(zhuǎn)換成相應(yīng)的機(jī)器語言目標(biāo)程序。與匯編程序不同,此處一條最簡(jiǎn)單的高級(jí)語言語句,可能對(duì)應(yīng)著一組機(jī)器指令。6.1.2為什么要用匯編語言編寫程序?yàn)槭裁催€要學(xué)習(xí)和使用匯編語言呢?主要有以下幾點(diǎn):(1)匯編語言非常接近機(jī)器語言程序,通過編制匯編語言程序,可以更清楚地了解計(jì)算機(jī)的工作過程。(2)現(xiàn)在的微機(jī)系統(tǒng)中,底層的一些功能仍然靠匯編語言程序來實(shí)現(xiàn)。(3)匯編語言程序的效率通常高于高級(jí)語言程序。6.1.3匯編語言的語句種類及其格式1.指令語句每一條指令語句在匯編時(shí)都要產(chǎn)生一個(gè)可供機(jī)器執(zhí)行的機(jī)器目標(biāo)代碼,所以這種語句又叫可執(zhí)行語句。指令語句的格式如下:標(biāo)號(hào):(前綴指令)助記符(操作符);(注釋)(1)標(biāo)號(hào)。這是一個(gè)任選字段。標(biāo)號(hào)是指令語句的標(biāo)識(shí)符,在語句之首,必須以“:”作為結(jié)束符。標(biāo)號(hào)的組成規(guī)則如下:①必須由字母、數(shù)字(0,…,9)及特殊符號(hào)(?,·,@,-,$)組成,且必須以字母打頭。②字符總數(shù)限制在31個(gè)以內(nèi)。③不能使用屬于系統(tǒng)專用保留字(Reservedword)。保留字主要有CPU中各寄存器名(如AX,CS);指令助記符(如MOV,ADD);偽指令(SEGMENT,DB);表達(dá)式中的運(yùn)算符(如GE,EQ)和屬性操作符(如PTR,OFFSET,SEG等)。語句格式中帶()的項(xiàng),是可有可無的項(xiàng)。如果有此項(xiàng)時(shí),書寫時(shí)不能加()括號(hào)。在有些指令語句中,需要在助記符前加前綴指令(例如LOCK或REP),中間應(yīng)用空格使兩者分開,如REPMOVSB。(2)指令助記符。這是為指令操作碼規(guī)定的符號(hào)。任何指令語句都需要此部分,它表示了指令語句的基本操作功能。如MOV是傳送指令的助記符,ADD是加法指令的助記符。(3)操作數(shù)。操作數(shù)可以根據(jù)指令的功能需要,可不帶操作數(shù),帶1個(gè)操作數(shù)或2個(gè)操作數(shù),若有兩個(gè)操作數(shù)時(shí),中間用“,”號(hào)分開。例如,NOP;STD;INCSI;ADDBL,30H。而操作數(shù)與助記符之間必須以空格分隔。(4)注釋。注釋是為方便程序人員閱讀程序而加的說明。它既不影響源程序的匯編,也不會(huì)出現(xiàn)在目標(biāo)程序中。通常并不要求每個(gè)匯編語句都應(yīng)加注釋。6.1.4常數(shù)、標(biāo)號(hào)、變量及表達(dá)式1.常數(shù)常數(shù)就是指令中出現(xiàn)的那些固定值,可以分為數(shù)值常數(shù)和字符串常數(shù)兩類。例如,立即數(shù)尋址時(shí)所用的立即數(shù),直接尋址時(shí)所用的地址,ASCII字符等都是常數(shù)。常數(shù)除了自身的值以外,沒有其它屬性的數(shù)值。在源程序中,數(shù)值常數(shù)按其基數(shù)的不同,可有二進(jìn)制數(shù)、八進(jìn)制數(shù)、十進(jìn)制數(shù)、十六進(jìn)制數(shù)等幾種不同的表示形式。匯編語句中用不同的后綴加以區(qū)別。①二進(jìn)制數(shù):數(shù)字后面跟字母B。如:00101101B②八進(jìn)制數(shù):用數(shù)字0~7表示,數(shù)字后跟字母Q或字母O。例如:177567Q(或177567O)263Q(或263O)③十進(jìn)制數(shù):數(shù)字后跟字母D或不跟字母。例如:17893D(或17893)。④十六進(jìn)制數(shù):十六進(jìn)制數(shù)用0~9及A~F表示。后面跟字母H。如:B7H,2031H。還應(yīng)指出,匯編語句中的數(shù)值常數(shù)的第一位必須是數(shù)字,否則匯編時(shí)將被看成是標(biāo)識(shí)符。如常數(shù)B7H在語句中應(yīng)寫成0B7H,F(xiàn)FH應(yīng)寫成0FFH。字符串常數(shù)是由單引號(hào)‘’括起來的一串字符。例如:‘ABCDEFG’和‘179’。單引號(hào)內(nèi)的字符在匯編時(shí)都以ASCII的代碼形式存放在存儲(chǔ)單元中。如上述兩字符串其ASCII代碼分別為41H、42H、43H、44H,…,4BH和31H、37H、39H。字符串最長(zhǎng)允許有255個(gè)字符。2.標(biāo)號(hào)標(biāo)號(hào)是用符號(hào)表示的地址,稱為符號(hào)地址,用以指示此指令語句所在的地址。標(biāo)號(hào)有3個(gè)屬性:段地址、偏移地址和類型。標(biāo)號(hào)的段地址和偏移地址屬性是指標(biāo)號(hào)對(duì)應(yīng)的指令首字節(jié)所在的段地址和段內(nèi)的偏移地址。標(biāo)號(hào)的類型屬性有兩種:NEAR和FAR類型。標(biāo)號(hào)如定義成NEAR類型,表示標(biāo)號(hào)僅在本段內(nèi)被引用;如定義成FAR類型,表示標(biāo)號(hào)可以在段間使用。在轉(zhuǎn)移和調(diào)用指令中常將標(biāo)號(hào)作為轉(zhuǎn)移目標(biāo)地址使用。3.變量變量是與一個(gè)數(shù)據(jù)項(xiàng)的第一字節(jié)相對(duì)應(yīng)的標(biāo)識(shí)符,它表示該數(shù)據(jù)項(xiàng)第一字節(jié)在現(xiàn)行段中的偏移量。變量的值在程序運(yùn)行期間可隨時(shí)修改。變量具有3個(gè)屬性: ①段地址(SEG):變量所在段的段地址; ②偏移地址(OFFSET):變量所在段內(nèi)的偏移地址; ③類型(TYPE):變量的類型是所定義的每個(gè)變量所占據(jù)的字節(jié)數(shù)。在匯編語言中,變量是通過偽指令來定義的,其格式如下:變量名DB表達(dá)式;定義字節(jié)變量。變量名DW表達(dá)式;定義字變量。變量名DD表達(dá)式;定義雙字變量。變量名DQ表達(dá)式;定義長(zhǎng)字變量。變量名DT表達(dá)式;定義一個(gè)十字節(jié)變量。上述偽指令的格式中的表達(dá)式可以有以下幾種情況:(1)一個(gè)或多個(gè)常數(shù)或某個(gè)運(yùn)算公式(其值應(yīng)為常數(shù))。當(dāng)為多個(gè)常數(shù)或運(yùn)算式時(shí),其間用逗號(hào)隔開。在這種情況下,DB將給定常數(shù)定義為字節(jié)。DW將給定常數(shù)定義為字(兩個(gè)字節(jié)),并給它分配兩個(gè)存儲(chǔ)單元,低位字節(jié)數(shù)占低地址單元,高位字節(jié)數(shù)占高地址單元。DD將給定常數(shù)定義為雙字,分配4個(gè)存儲(chǔ)單元。同理,DQ則分配8個(gè)存儲(chǔ)單元,DT分配10個(gè)存儲(chǔ)單元。當(dāng)定義的變量有幾個(gè)操作數(shù)時(shí),則應(yīng)從左到右由低地址向高地址順序排列所定義的常數(shù)。(2)帶引號(hào)的字符串。字符串必須用單引號(hào)括住,字符串的字符不超過255個(gè)。DB對(duì)每一個(gè)字符分配一個(gè)存儲(chǔ)單元,字符是由左向右按地址遞增的順序排列。例如KFDB‘ABC’;按41H、42H、43H的順序由低地址到高地址分配存儲(chǔ)地址。當(dāng)操作數(shù)有多個(gè)字符串時(shí),也是從左到右按地址遞增順序分配各字符串的存放單元。(3)用問號(hào)作為表達(dá)式。不帶引號(hào)的問號(hào)是一個(gè)保留字,它可用作數(shù)據(jù)類型偽指令DB、DW、DD語句中的表達(dá)式。用它告訴匯編程序,留出DB、DW、DD所分配的存儲(chǔ)單元,原先內(nèi)存內(nèi)容不改變。例如:SURDW?;預(yù)留一個(gè)字(二個(gè)字節(jié))。SUMDB?;預(yù)留一個(gè)字節(jié)。(4)帶DUP(重復(fù)方式)表達(dá)式。DUP是表達(dá)式中的一個(gè)操作符。此時(shí)表達(dá)式的格式為重復(fù)次數(shù)DUP(表達(dá)式)DUP操作符的后面為一個(gè)加圓括號(hào)的表達(dá)式。DUP表示的功能是把表達(dá)式重復(fù)預(yù)置,重復(fù)的次數(shù)由DUP前面的常數(shù)決定。例如:TABADB120DUP(0);分配120個(gè)字節(jié),并預(yù)置為零。TABBDW1000DUP(?);分配1000個(gè)字,不改變?cè)葍?nèi)容。TABCDB10DUP(′WELCOME′,0AH,0BH);表達(dá)式由一個(gè)字符串‘WELCOME’和兩個(gè)常數(shù)0AH,0BH組成,并重復(fù)預(yù)置;10次。還應(yīng)指出,DUP可以重疊使用,例如:TABDDB2DUP(0,3DUP(1))DW100DUP(5DUP(5),38FBH)第一句是用DB定義的,表達(dá)式的外括號(hào)中的3DUP(1)表示把由DB定義的預(yù)置為1的字節(jié)數(shù)重復(fù)3次。這樣,2DUP(0,3DUP(1))=2DUP(0,1,1,1)。再根據(jù)定義,把(0,1,1,1)重復(fù)2次,這樣2DUP(0,3DUP(1))=0,1,1,1,0,1,1,1。整個(gè)語句的意思是:給命名為TABD的數(shù)組分配8個(gè)字節(jié)單元,并由低地址到高地址順序放置0,1,1,1,0,1,1,1。第二個(gè)語句中(5DUP(5),38FBH)=(5,5,5,5,5,38FBH)。然后再把括號(hào)內(nèi)由6個(gè)元素組成的數(shù)組重復(fù)100次。(5)地址表達(dá)式(只能用于DW或DD)。操作數(shù)為地址表達(dá)式時(shí),應(yīng)遵循下列規(guī)則:①當(dāng)用DW定義地址表達(dá)式時(shí),地址表達(dá)式中的變量名稱表示該變量的第一個(gè)存儲(chǔ)單元的偏移地址,地址表達(dá)式中的標(biāo)號(hào)表示它所代表的指令(或偽指令)的第一個(gè)字節(jié)的偏移地址。②當(dāng)用DD定義地址表達(dá)式時(shí),低位字用于預(yù)置偏移地址,高位字用于預(yù)置段地址,這些數(shù)值都是在定位時(shí)裝入的。③地址表達(dá)式中的變量或標(biāo)號(hào)可與常數(shù)值相加減。對(duì)于變量來說,運(yùn)算結(jié)果的類型不變;對(duì)標(biāo)號(hào)來說,運(yùn)算結(jié)果仍表示原標(biāo)號(hào)所在段中的偏移地址。④變量或標(biāo)號(hào)不能與變量或標(biāo)號(hào)相加,但可相減,結(jié)果是沒有屬性的純數(shù)值。定義地址表達(dá)式舉例如下:A1DWVALUE;定義變量A1為VALUE的偏移地址。A2DWVALUE+5;定義變量A2為VALUE第6個(gè)字節(jié)的偏移地址。A3DWVALUE-3;定義變量A3為VALUE前3個(gè)字節(jié)的偏移地址。A4DDVALUE;高位字為VALUE所在段的段地址,低位字為VALUE的 偏移地址。定義變量的偽指令的功能是在變量名所對(duì)應(yīng)的地址開始的內(nèi)存區(qū)依次存入各項(xiàng)值。當(dāng)同時(shí)有幾個(gè)變量定義語句時(shí),將按照由上到下書寫順序,由低地址到高地址給每個(gè)變量語句中的表達(dá)式分配存儲(chǔ)單元。例如:DATA1DB20HDATA2DW0204H,100HDATA3DB(-1*3),(15/3)DATA4DD12345HDATA5DB′0123′DATA6DW′Ab′,′C′,′D′DATA7DB?DATA8DD?DATA9DB5DUP(00)

DATA10DW3DUP(?)圖6.2各變量在內(nèi)存中分配的單元4.表達(dá)式(1)操作數(shù)。一個(gè)操作數(shù)在內(nèi)容上可能代表一個(gè)數(shù)據(jù),也可能代表一個(gè)存儲(chǔ)單元的地址。對(duì)于數(shù)據(jù),最簡(jiǎn)單的表達(dá)方式就是用常數(shù)形式表示,如20H,1234H,0FDH。匯編語言源程序中也常用標(biāo)號(hào)來表示數(shù)據(jù),如可用PORTA表示一個(gè)端口地址號(hào),而在源程序中應(yīng)對(duì)PORTA作出定義,使它等于某個(gè)常數(shù)。在源程序中,存儲(chǔ)器地址常用標(biāo)識(shí)符(也稱標(biāo)號(hào))來表示。如規(guī)范程序中常用START、MOVE、CLOSE作為標(biāo)號(hào)。源程序中的地址標(biāo)號(hào)常常作為轉(zhuǎn)移指令的轉(zhuǎn)移地址或調(diào)用指令的調(diào)用地址。這些標(biāo)號(hào)所代表的具體的地址值應(yīng)由段地址和偏移地址兩部分組成。(2)運(yùn)算符。用一個(gè)運(yùn)算符可以對(duì)一個(gè)或幾個(gè)操作數(shù)進(jìn)行運(yùn)算,構(gòu)成一個(gè)表達(dá)式。源程序中表達(dá)式經(jīng)匯編后為一個(gè)值。匯編語言中有5類運(yùn)算符,即①算術(shù)運(yùn)算符(ArithmeticOperators);②邏輯運(yùn)算符(LogicalOperators);③關(guān)系運(yùn)算符(RelationalOperators);④分析運(yùn)算符(AnalyticOperators);⑤綜合運(yùn)算符(SyntheticOperators)。①算術(shù)運(yùn)算符包括加(+)、減(-)、乘(*)、除(/)和取模運(yùn)算(MOD)。取模運(yùn)算是取兩數(shù)相除的余數(shù),但兩操作數(shù)必須為正整數(shù)。例如

82MOD16結(jié)果為2(相當(dāng)于取低4位的值)。B5HMOD20H結(jié)果為21(相當(dāng)于取低5位的值)。20HMOD7結(jié)果為4。②邏輯運(yùn)算符。邏輯運(yùn)算符包括與(AND)、或(OR)、非(NOT)和異或(XOR)。邏輯運(yùn)算符又能對(duì)常數(shù)進(jìn)行運(yùn)算,所得的結(jié)果也是常數(shù)。兩數(shù)進(jìn)行邏輯運(yùn)算是兩數(shù)的對(duì)應(yīng)位按位進(jìn)行相應(yīng)的邏輯運(yùn)算。例如:11001100BAND11110000B;結(jié)果為11000000B。11001100BOR11110000B;結(jié)果為11111100B。 NOTFFH;結(jié)果為00H。11001100BXOR11110000B;結(jié)果為00111100B。

應(yīng)注意的是,邏輯操作符和邏輯運(yùn)算指令的操作助記符是相同的。只有當(dāng)它們出現(xiàn)在指令的操作數(shù)部分時(shí),匯編程序才將它看成是邏輯運(yùn)算符。例如:ANDDX,PORTAAND0FEHAND操作助記符邏輯運(yùn)算符③關(guān)系運(yùn)算符。關(guān)系運(yùn)算符有:相等EQ(Equal)、不等NE(NoEqual)、小于LT(LessThan)、大于GT(GreaterThan)、小于或等于LE(LessthanorEqual)、大于或等于GE(GreaterthanorEqual)。參加關(guān)系運(yùn)算的兩個(gè)操作數(shù)必須都是操作數(shù)或者是同一段中的存儲(chǔ)單元地址,結(jié)果總是一個(gè)數(shù)值。當(dāng)關(guān)系成立時(shí),其結(jié)果為全1,當(dāng)關(guān)系不成立時(shí),其結(jié)果為全0。例如:MOVBX,PORTLT5表示如果PORT的值確實(shí)小于5,則匯編后得到的代碼等效于指令MOVBX,0FFFFH。如果PORT的值大于或等于5,等效于指令MOVBX,0。所以關(guān)系運(yùn)算符一般不單獨(dú)使用,往往和邏輯運(yùn)算符組合起來使用。例如:MOVBX,((PORTLT5)AND20)OR((PORTGE5)AND30)表示當(dāng)PORT小于5時(shí),上述指令等效于MOVBX,20當(dāng)PORT大于或等于5時(shí),上述指令等效于MOVBX,30④分析運(yùn)算符和綜合運(yùn)算符。利用分析運(yùn)算符可以把一個(gè)存儲(chǔ)單元地址分解為段地址和偏移量。利用綜合運(yùn)算符可以規(guī)定存儲(chǔ)單元的性質(zhì)。ASM匯編語言的分析運(yùn)算符有OFFSET、SEG、TYPE、SIZE和LENGTH。如表6.1所示。例如:MOVDX,OFFSETDATA1;取出標(biāo)號(hào)DATA1的偏移量到DX中。MOVAX,SEGDATA1 ;取出DATA1的段地址送到DS中。MOVDS,AX

表6.1分析運(yùn)算符表達(dá)式帶分析運(yùn)算符的表達(dá)式表達(dá)式的意義OFFSET變量名或標(biāo)號(hào)取出變量名或標(biāo)號(hào)所在段的偏移地址SEG變量名或標(biāo)號(hào)取出變量名或標(biāo)號(hào)所在段的段地址TYPE變量名或標(biāo)號(hào)取出變量名或標(biāo)號(hào)的類型SIZE變量名取出變量的大小LENGTH變量名取出變量的長(zhǎng)度類型TYPE運(yùn)算符用來說明變量名或標(biāo)號(hào)分配存儲(chǔ)單元的類型,如是字節(jié)分配類型,對(duì)應(yīng)值為1;如是字分配類型,對(duì)應(yīng)值為2;如是雙字分配類型,對(duì)應(yīng)值為4。如表6.2所示。表6.2存儲(chǔ)單元分配類型和對(duì)應(yīng)值存儲(chǔ)單元分配類型對(duì)應(yīng)值字節(jié)1字2雙字4變量的類型是由偽指令DB、DW和DD來定義的。比如:

DATA3DB(-1*3),(15*3);定義DATA3為字節(jié)變量。

此時(shí)TYPEDATA3對(duì)應(yīng)的值為1,以字節(jié)分配存儲(chǔ)單元。又如TABADB20DUP(?),那么TYPETABA也等于1。運(yùn)算符LENGTH對(duì)于變量中使用DUP的情況,匯編程序?qū)⒔o出分配給該變量的單元數(shù)(分配單元可以以字節(jié)、字或雙字為單位計(jì)算),而對(duì)于其它情況則給出值1。例如:

DATA6DW′Ab′,′C′,′D′

此時(shí)LENGTHDATA6等于1。又如: ABCDW100DUP(?)此時(shí)LENGTHABC等于100。運(yùn)算符SIZE用來計(jì)算一個(gè)變量存儲(chǔ)區(qū)所占用的字節(jié)數(shù)。同樣,以ABC變量為例,SIZEABC等于200,因它占用的字節(jié)為200(100個(gè)字)。由上可知,SIZE、LENGTH和TYPE之間有如下關(guān)系:SIZE=LENGTH*TYPEASM的綜合運(yùn)算符有PTR和THIS。PTR用來對(duì)存儲(chǔ)單元規(guī)定類型。PRT運(yùn)算符所表示操作數(shù)的格式為類型PTR表達(dá)式格式中的類型可以是:BYTE、WORD、DWORD、NEAR和FAR。前3個(gè)類型是變量類型,后兩個(gè)是標(biāo)號(hào)類型。格式中的表達(dá)式可以是變量名、標(biāo)號(hào)或其它地址表達(dá)式。PTR運(yùn)算符的功能是用來重新定義已定義過的變量或標(biāo)號(hào)的類型。例如:

MOVBYTEPTR[1000],0

此語句是用BYTE和PTR規(guī)定地址號(hào)為1000存儲(chǔ)單元為字節(jié)單元。所以執(zhí)行結(jié)果是將[1000]單元清零。如使用下列語句:

MOVWORDPRT[1000],0此語句是規(guī)定地址號(hào)1000存儲(chǔ)單元為字單元,所以執(zhí)行結(jié)果應(yīng)將[1000]及[1001]兩單元清零。又如,若已定義DATA3是字變量,則程序中需將它作為字節(jié)變量使用時(shí),必須用PTR來重新定義其類型??梢杂萌缦抡Z句:MOVBYTEPTRDATA3,AL

它的功能是將(AL)送至DATA3對(duì)應(yīng)的一個(gè)字節(jié)中。應(yīng)指出變量DATA3僅在此語句中臨時(shí)被定義成字節(jié)變量,DATA3原先定義的字變量類型沒有修改。THIS綜合運(yùn)算符也可以用來改變存儲(chǔ)區(qū)的類型,稱類型指定運(yùn)算符。THIS運(yùn)算符的運(yùn)算對(duì)象是類型(BYTE、WORD、DWORD)或距離(NEAR、FAR),用于規(guī)定所指變量或標(biāo)號(hào)類型屬性或距離屬性。例如:

XYZEQUTHISBYTE此等價(jià)語句的功能是把字節(jié)類型BYTE屬性賦予變量XYZ。它等效于下述表達(dá)式:

BYTEPTRXYZTHIS可提高訪問標(biāo)號(hào)的靈活性,如:FAROUTEQUTHISFAR此語句的功能是把段間距離屬性FAR賦予標(biāo)號(hào)FAR-OUT。6.1.5偽指令1.方式偽指令(1).8086。在這條偽指令后,匯編程序?qū)⒃?086/8088方式下操作,實(shí)際上這是微處理器的默認(rèn)操作狀態(tài)。(2).386。在這條偽指令后,匯編程序?qū)⒃?0386方式下操作。如果想利用32位寄存器,必須加上這條偽指令。2.賦值偽指令EQU在匯編語言程序中,當(dāng)某個(gè)表達(dá)式被多次引用時(shí),常采用給這個(gè)表達(dá)式賦予一個(gè)名稱,這樣源程序中就可以以名稱代替表達(dá)式;另外常使用標(biāo)號(hào)來代表數(shù)據(jù)、數(shù)據(jù)地址或程序地址。這種賦予表達(dá)式或數(shù)據(jù)/地址以名稱/標(biāo)號(hào)的偽指令EQU有兩種格式,即①表達(dá)式名稱EQU表達(dá)式②新標(biāo)號(hào)EQU老標(biāo)號(hào)在①種格式中,表達(dá)式可以是常數(shù)或者地址表達(dá)式,例如:ABCEQU2000H;表示名稱ABC就是等價(jià)于數(shù)值2000H。XYZEQU[BP+5];名稱XYZ就代表地址表達(dá)式[BP+5]。ECONEQUE7HMOD10;ECON是代表取模運(yùn)算后的余在②種格式中,可以對(duì)以前已經(jīng)賦過值的標(biāo)號(hào)以新的標(biāo)號(hào),例如:

AADEQUPAR-3;新標(biāo)號(hào)AAD等價(jià)于老標(biāo)號(hào)PAR-3的值。COUNTEQUCX;使COUNT和寄存器CX具有相同的意義。如果有了上列語句,則指令語句MOVAL,AAD等價(jià)于MOVAL,PAR-3MOVAX,COUNT等價(jià)于MOVAX,CX3.定義變量偽指令前面已經(jīng)提及定義變量的偽指令,就是給變量分配存儲(chǔ)單元。這些偽指令是DB、DW、DD、DQ、DT。DB用來定義字節(jié),DW定義字,DD定義雙字,DQ定義4個(gè)字,DT定義10個(gè)字。這些偽指令的格式及用法見前述。

4.定義存儲(chǔ)單元類型的偽指令BYTE、WORD、DWORD定義存儲(chǔ)單元的偽指令并不是單獨(dú)使用,而是和指令結(jié)合起來使用的。利用這些偽指令,對(duì)存儲(chǔ)單元類型進(jìn)行規(guī)定。例如:MOVBYTEPTR[DI],00MOVWORDPTR[1000],00INCBYTEPTR[DI]JMPDWORDPTR[2000]

5.LABEL本條偽指令用于定義標(biāo)號(hào)名稱和屬性,它和下一條指令共享存儲(chǔ)器單元。格式: 名字LABEL類型例如:BYTE-ARRAYLABELBYTEWORD-ARRAYDW100DUP(?)在第二條語句中指明了有100個(gè)字存儲(chǔ)單元,它們的符號(hào)地址名為WORD-ARRAY,但在第一行說明這100個(gè)字存儲(chǔ)單元可以看成200個(gè)字節(jié)存儲(chǔ)單元。符號(hào)地址名為BYTE-ARRAY。這樣,當(dāng)我們?cè)L問存儲(chǔ)器操作時(shí),就可以有兩種觀點(diǎn):(1)MOVWORD-ARRAY,0;是把第一個(gè)字置為0。(2)MOVBYTE-ARRAY,0;是把第一個(gè)字節(jié)置為0。利用LABEL偽指令,對(duì)存儲(chǔ)器單元就可以有不同的劃分,這為訪問存儲(chǔ)器單元提供了較大的靈活性。

6.SEG和OFFSETSEG操作符返回存儲(chǔ)器地址操作數(shù)的段地址部分,而OFFSET返回存儲(chǔ)器地址操作數(shù)的段內(nèi)偏移地址部分。例如:

…NUMBER-1DD?…MOVAX,SEGNUMBER-1MOVDS,AX ;段地址進(jìn)入DS。MOVSI,OFFSETNUMBER-1;偏移地址進(jìn)入SI。7.TYPE、SIZE和LENGTH表6.3存儲(chǔ)器地址操作數(shù)類型值存儲(chǔ)器操作數(shù)類型值(DB)字節(jié)數(shù)據(jù)1(DW)字?jǐn)?shù)據(jù)2(DD)雙字?jǐn)?shù)據(jù)4(DF)三字?jǐn)?shù)據(jù)6(DQ)四字?jǐn)?shù)據(jù)8(DT)五字?jǐn)?shù)據(jù)10NEAR指令單元-1FAR指令單元12這里,字節(jié)、字等的類型就是它們所占用的字節(jié)數(shù),而NEAR和FAR指令單元的類型值沒有物理意義。SIZE和LENGTH只應(yīng)用于存儲(chǔ)器地址操作數(shù)。LENGTH返回一個(gè)你定義的數(shù)的尺寸的單元數(shù)。SIZE則返回存儲(chǔ)器地址操作數(shù)占用的字節(jié)數(shù)。例如:LARGE-NUMDD40DUP(0)這里是按雙字尺寸分配存儲(chǔ)單元的,所以LENGTH(LARGE-NUM)是40,而SIZE(LARGE-NUM)是160??梢钥闯?,如果X是地址操作數(shù),則

SIZE(X)=(LENGTH(X))*(TYPE(X))8.段定義偽指令(1)SEGMENT/ENDS偽指令。偽指令SEGMENT和ENDS總是成對(duì)使用的。用這對(duì)偽指令來指定段的名稱和范圍,還可指明段的定位類型(aligntype)、組合類型(combinetype)和分類名。段定義偽指令的格式為

段名SEGMENT[定位類型][組合類型][分類名]…}本段程序內(nèi)容(指令語句或偽指令語句)段名ENDS從SEGMENT偽指令之后出現(xiàn)的指令和偽指令都被認(rèn)為是在該段之內(nèi),直至ENDS出現(xiàn)為止。段定義格式中,帶有‘[]’部分根據(jù)需要可有可無。還應(yīng)指出,當(dāng)用于定義數(shù)據(jù)段、附加數(shù)據(jù)段和堆棧段時(shí),處于SEGMENT/ENDS偽指令中間的語句,只能包括偽指令語句,不能包括指令語句,一般格式為

段名SEGMENT…}數(shù)據(jù)定義,存儲(chǔ)單元分配等偽指令語句段名ENDS當(dāng)由SEGMENT/ENDS定義代碼段時(shí),中間的語句可包括指令語句和與指令有關(guān)的偽指令語句。一般格式為

段名SEGMENT…}指令語句和與偽指令有關(guān)的偽指令語句段名ENDS段定義格式中,各部分的用法說明如下:段名:所定義段的名稱。段名是標(biāo)識(shí)符,同一段的SEGMENT/ENDS偽指令前的段名必須一致。一個(gè)段一經(jīng)定義,其中指令的標(biāo)號(hào)、變量等在段內(nèi)的偏移地址就已排定,它們都在同一個(gè)段地址控制之下,整個(gè)段占用的存儲(chǔ)空間大小也就確定。由SEGMENT/ENDS偽指令所定義的段,通常小于64K單元,而且經(jīng)過匯編和連接,定義的各段不互相覆蓋。一個(gè)源程序模塊的典型結(jié)構(gòu)如下:STACK-SEGSEGMENT;STACK-SEGENDS;…定義堆棧段DATA-SEGSEGMENT;DATA-SEGENDS;EXTRA-SEGSEGMENT;EXTRA-SEGENDS;CODE-SEGSEGMENT;START:CODE-SEGENDS;ENDSTART;源程序模塊結(jié)束………定義數(shù)據(jù)段定義附加數(shù)據(jù)段定義代碼(即指令)段段定義格式中SEGMENT偽指令后,用‘[]’括起來的不是規(guī)定的語法符號(hào),而是表示該項(xiàng)是可選的,有時(shí)可以全部省略。當(dāng)它們存在時(shí),用于指明段間的聯(lián)系形態(tài),說明段定義的輔助屬性?,F(xiàn)說明如下:①定位類型。定位類型給出實(shí)際段起點(diǎn)的類型。它有PAGE、PARA、WORD、BYTE四種類型。PAGE:表示相應(yīng)的段必須從某一頁(yè)(256個(gè)字節(jié))的邊界開始。即段的起始地址能為256整除。此時(shí)20位的段地址為PAGE=××××××××××××00000000BPARA:表示段的起點(diǎn)是從存儲(chǔ)器中的某一個(gè)節(jié)(一節(jié)等于16個(gè)字節(jié))的邊界開始。也即段的起始地址能被16整除。此時(shí)20位的段起始地址為PARA=××××××××××××××××0000BWORD:表示段的起點(diǎn)可以從任何一個(gè)字的邊界(偶地址)開始。即地址能被2整除。段起始地址為WORD=×××××××××××××××××××0BBYTE:表示段的地址可以從存儲(chǔ)器的任何地址開始。段起始地址為BYTE=××××××××××××××××××××B對(duì)于PAGE和PARA類型其段內(nèi)的偏移地址都是從0開始的。而對(duì)WORD類型,段內(nèi)偏移地址不一定從0開始,合理選擇定位類型,能夠使得在進(jìn)行段和模塊的定位連接時(shí),可充分地利用存儲(chǔ)器空間。②組合類型。組合類型在模塊式程序設(shè)計(jì)中表示該段和其它同名段間的組合連接方法。如果在SEGMENT偽指令后面沒有指明組合類型,則匯編程序ASM認(rèn)為這個(gè)段是不準(zhǔn)備與別的段相連接的。組合類型有以下5種選擇:PUBLIC:表示該段可與模塊連接時(shí)所遇到的其它同名段在滿足定位類型的前提下依次連接起來。連接的順序由連接程序LINK確定。COMMON:表示該段與別的模塊中的所有其它同名同類別段共享相同的存儲(chǔ)空間。即各段都是從相同的地址開始,具有同樣的段地址,且互相覆蓋。連接后,段的長(zhǎng)度等于最長(zhǎng)的COMMON段的長(zhǎng)度。AT表達(dá)式:表示相應(yīng)段定位在由表達(dá)式求值得到的節(jié)邊界地址上。表達(dá)式也可以是一個(gè)常數(shù)。例如,AT2345H表示該段定位在實(shí)際物理地址23450H處。STACK:與PUBLIC組合類型的處理方式相同,即把不同模塊中帶有STACK組合類型的同名段連接起來,使這些同名段都從同一基地址開始。但STACK組合方式僅用于堆棧段。MEMORY:表示在連接時(shí),本段應(yīng)裝在被連接的其它段之上,即在同名段中具有最高的地址。若連接時(shí)具有MEMORY組合類型的段不止一個(gè),則只有第一段才當(dāng)成MEMORY組合類型來處理,其它的段將重疊,即按COMMON組合類型來處理。③類名。類名是程序員任選的一個(gè)字符串,使用時(shí)必須用單引號(hào)括起來‘類名’。連接時(shí),將把不同模塊中相同‘類名’的各段在物理地址上相鄰的連接在一起,其順序則與LINK時(shí)提供的各模塊順序一致。(2)ORG偽指令。偽指令ORG用來規(guī)定目標(biāo)程序存放單元的偏移量。它的格式如下:

ORG表達(dá)式其中表達(dá)式以65536(216)為模進(jìn)行計(jì)算,計(jì)算結(jié)果應(yīng)是一個(gè)不為負(fù)的常數(shù)。若表達(dá)式中有標(biāo)識(shí)符,則標(biāo)識(shí)符必須是已經(jīng)定義過的。匯編程序ASM規(guī)定ORG偽指令不能帶標(biāo)識(shí)符。例如: START:ORG2000H是非法語句。如果在源程序中的第一條指令用了如下偽指令:ORG2000H,則匯編程序?qū)阎噶钪羔業(yè)P的值置成2000H,目標(biāo)程序的第一個(gè)字節(jié)將放置在2000H單元,后面的程序就會(huì)依次順序存放。當(dāng)遇上另一個(gè)ORG語句時(shí),目標(biāo)程序的存放地址才會(huì)從新的ORG語句指定的地址單元存放。例如,若當(dāng)前的(IP)=2400H,這時(shí)若又遇到如下ORG語句:

ORG2464H則匯編程序會(huì)修改IP內(nèi)容,使(IP)=2464H,并以此存儲(chǔ)單元開始存放目標(biāo)程序。這樣就保留了100個(gè)字節(jié)的存儲(chǔ)空間。ORG偽指令可以放置在源程序中的任何位置。(3)ASSUME偽指令。ASSUME偽指令語句用來告訴匯編程序在指令執(zhí)行期間內(nèi)存的哪一段是數(shù)據(jù)段,哪一段是堆棧段,哪一段是代碼段。ASSUME偽指令語句的格式如下:

ASSUME段寄存器名:段名符[,段寄存器名:段名符,…]上述格式中[]內(nèi)的內(nèi)容可有可無。例如:

ASSUMECS:MYCODE,DS:MYDATAASSUMEES:MYEXTRA,SS:MYSTACK這兩個(gè)語句是將所定義的段MYCODE、MYDATA、MYEXTRA和MYSTACK分別置于段寄存器CS、DS、ES和SS的控制之下。ASSUME語句只能安排在代碼段內(nèi),一般應(yīng)排在代碼段作為首始指令。ASSUME語句中的‘段寄存器名:段名符’可以有一項(xiàng),也可以有多項(xiàng),如果一行寫不下,可分成兩個(gè)ASSUME語句。一個(gè)源程序模式至少包括一個(gè)段,當(dāng)指令(即代碼)、數(shù)據(jù)及堆棧區(qū)都將集中在一個(gè)段內(nèi)時(shí),ASSUME語句的格式應(yīng)該是為

ASSUMECS:MYCODE,DS:MYCODE,ES:MYCODE,SS:YCODE除了CS以外,各個(gè)段寄存器的實(shí)際值,還要用MOV指令來賦值。例如:…

MYCODESEGMENTASSUMECS:MYCOED,DS:MYDATA,ES:MYEXTRA,SS:MYSTACKSTART:MOVAX,MYDATAMOVDS,AXMOVAX,MYEXTRAMOVES,AXMOVAX,MYSTACKMOVSS,AX…MYCODEENDS …

9.過程定義偽指令PROC,ENDP,NEAR,F(xiàn)AR在ASM語言中,過程的含義和子程序是一樣的。一個(gè)過程可以被其它程序所調(diào)用,它的最后一條指令總是返回指令,用以控制此過程在執(zhí)行完畢后,返回到主程序。定義過程的偽指令PROC/ENDP總是成對(duì)出現(xiàn)的,在這兩條偽指令間的內(nèi)容就作為一個(gè)過程,即一個(gè)子程序。有關(guān)PROC/ENDP偽指令的格式定義在第4章中已作了介紹,現(xiàn)僅舉例說明PROC/ENDP等一組偽指令的用法。下面是實(shí)現(xiàn)多字節(jié)BCD碼相加的完整的程序片段:DATASEGMENT;定義數(shù)據(jù)段。FIRSTDB11,22,33,44;第一個(gè)加數(shù)。SECONDDB55,66,77,88;第二個(gè)加數(shù)。SUMDB4DUP(?);存放結(jié)果單元。DATAENDSSTACKSEGMENT;定義堆棧段。STADB20DUP(?);設(shè)置堆棧長(zhǎng)度為20個(gè)字節(jié)。TOPEQULENGTHSTASTACKENDSCODESEGMENT;定義代碼段。ASSUMECS:CODE,DS:DATA,SS:STACKSTART:MOVAX,DATA;裝入段寄存器實(shí)際值數(shù)據(jù)。 MOVDS,AX MOVAX,STACK;裝入段寄存器實(shí)際值堆棧。 MOVSS,AX MOVAX,TOP ;設(shè)置堆棧指針。 MOVSP,AX MOVSI,OFFSETFIRST;SI指向第一個(gè)加數(shù)。 MOVDI,OFFSETSUM;DI指向結(jié)果單元。 MOVBX,OFFSETSECOND;BX指向第二加數(shù)。 MOVCX,04 ;共4個(gè)字節(jié)長(zhǎng)。 CLD ;清方向標(biāo)志。 CLC ;清進(jìn)位標(biāo)志。ADITI:CALLAAA;調(diào)用多字節(jié)加法子程序。 LOOPADITI… ;繼續(xù)后面主程序。…AAA1PROCNEAR;單字節(jié)加法子程序。LODSB;取第一個(gè)加數(shù)。ADCAL,[BX];相加。DAA;十進(jìn)制調(diào)整。STOSB;結(jié)果送DI所指單元。INCBX;修改指針。RET;返回。AAAENDP;子程序結(jié)束。CODEENDS;程序段結(jié)束。ENDSTART;程序結(jié)束。10.定義結(jié)構(gòu)的偽指令STRUC/ENDS(1)結(jié)構(gòu)的定義。結(jié)構(gòu)偽指令的格式如下:

結(jié)構(gòu)名稱STRUC…結(jié)構(gòu)名稱ENDS

如果DB、DW或DD語句包括變量標(biāo)識(shí)符,則該標(biāo)識(shí)符表示一個(gè)字段的開始,稱為字段標(biāo)識(shí)符。例如,對(duì)上述所說的學(xué)生學(xué)業(yè)管理可采用以下所示的結(jié)構(gòu)形式:由DB、DW、DD偽指令所組成的語句序列STUDENT-RECORDSTRUCNAMEDB′LiPing′SEXDB0,0formale,1forfemaleAGEDB25HNUMBERDB′??????′MATHDB91HPHYSICALDB85HCIRCUITDB95H…STUDENT-RECORDENDS(2)結(jié)構(gòu)的存儲(chǔ)分配和預(yù)置。為了給結(jié)構(gòu)分配存儲(chǔ)空間或預(yù)置,必須有一個(gè)援用該結(jié)構(gòu)的語句,其格式如下: 變量結(jié)構(gòu)名稱〈賦值說明〉其中結(jié)構(gòu)名稱是指STRUC偽指令中的結(jié)構(gòu)名稱(在前面的例子中為STUDENT-RECORD),變量與結(jié)構(gòu)的起始點(diǎn)相對(duì)應(yīng),另外變量名要與字段標(biāo)識(shí)符一起使用方可訪問結(jié)構(gòu)中的各個(gè)字段(對(duì)上述的例子,變量名可用所管理的學(xué)生名表示,也可以用其它方法為變量命名)。賦值說明必須寫在尖括號(hào)‘〈〉’內(nèi),它由一系列常數(shù)表達(dá)式組成,一個(gè)字段一個(gè)表達(dá)式,由逗號(hào)分開;如果某個(gè)字段有某n個(gè)字段使用結(jié)構(gòu)定義中的預(yù)賦值,則相應(yīng)的表達(dá)式可省缺,但應(yīng)保留逗號(hào);如果全部表達(dá)式都省缺,則只要寫一對(duì)尖括號(hào);如果省缺的是最后面的一些字段,則可以省去逗號(hào)。此外,對(duì)字符串常量所表示的字段要替換的話,若替換的字符長(zhǎng)度大于原來形式參數(shù)的長(zhǎng)度,匯編程序?qū)⒆詣?dòng)截去多出的字符;若替換字符長(zhǎng)度小,則用最后的那個(gè)字符填滿剩余的存儲(chǔ)空間。例如,對(duì)上述的例子援用語句可以是:LiPingSTUDENT-RECORD〈,,,′891011′〉LuiYiSTUDENT-RECORD〈′LuiYi′,1,′891011′,80H〉(3)對(duì)結(jié)構(gòu)的訪問。通過援用語句對(duì)結(jié)構(gòu)進(jìn)行存儲(chǔ)空間分配和預(yù)置之后,結(jié)構(gòu)及其字段就以變量的形式出現(xiàn),可以像使用其它變量一樣使用。但對(duì)結(jié)構(gòu)的訪問必須用變量路徑名的方法進(jìn)行,路徑名的格式為變量名·字段名例如,對(duì)于前面的例子,若需要將學(xué)生A的年齡傳送到寄存器AL,則可以使用下列指令語句:

MOVAL,LiPing·AGE如果BX中存有變量LiPing的偏移地址,則下列語句與上述語句是等效的:MOVAL,[BX]·AGE11.IFELSEENDIF條件匯編偽指令MASM提供了功能強(qiáng)大的條件匯編偽指令,使用它的一般格式是:IF ;如果條件成立…[ELSE];[否則]…ENDIF;結(jié)束條件匯編語句其中IF有多種形式,它們是:IF操作數(shù);如果操作數(shù)不等于0時(shí)。IFE操作數(shù);如果操作數(shù)等于0時(shí)。IFDEF標(biāo)號(hào)或變量;如果標(biāo)號(hào)或變量已被定義時(shí)。IFNDEF標(biāo)號(hào)或變量;如果標(biāo)號(hào)或變量還沒被定義時(shí)。IFB〈變量〉;如果變量為空時(shí)。IFNB〈變量〉 ;如果變量不為空時(shí)。IFIDN〈操作數(shù)1〉,〈操作數(shù)2〉;如果〈操作數(shù)1〉等于〈操作數(shù)2〉時(shí)。IFDIF〈操作數(shù)1〉,〈操作數(shù)2〉;如果〈操作數(shù)1〉不等于〈操作數(shù)2〉時(shí)。IF1 ;如果匯編程序在第一遍掃描時(shí)。IF2 ;如果匯編程序在第二遍掃描時(shí)。在IF的形式中,尖括號(hào)“〈〉”中內(nèi)容是必需的。

12.邏輯運(yùn)算偽指令A(yù)ND、OR、XOR、NOT按位操作,運(yùn)算規(guī)則與它們作為指令時(shí)一樣,但只能用于算術(shù)表達(dá)式中。與指令A(yù)ND、OR、XOR、NOT區(qū)別如下:作為指令時(shí)它們用在最前面,且目的操作數(shù)必須為寄存器或存儲(chǔ)器操作數(shù);作為偽指令時(shí)它們用在數(shù)學(xué)表達(dá)式中,操作數(shù)在它們的兩邊,可以都是立即數(shù)。例如:

ANDAX,CX ;AND作為指令。MOVAX,OFEHAND145H;AND作為偽指令。ANDDX,CXANDOFA4CH;第一個(gè)作為指令,第二個(gè)是偽指令。

13.訪問外部標(biāo)識(shí)符的偽指令EXTRN、PUBLIC當(dāng)把若干個(gè)模塊連接在一起時(shí),必須解決其中的任一模塊能夠引用其它模塊中的某些變量或標(biāo)號(hào)的問題,這里引入的定義訪問外部標(biāo)識(shí)偽指令EXTRN和PUBLIC就是提供解決這個(gè)問題的方法。如果一個(gè)標(biāo)識(shí)符只在一個(gè)模塊中定義過,那么就說它相對(duì)這個(gè)模塊是一個(gè)內(nèi)部標(biāo)識(shí)符或局部標(biāo)識(shí)符;如果一個(gè)標(biāo)識(shí)符在其模塊內(nèi)未定義過,而是在其它模塊中定義,那么它就被稱為相對(duì)該模塊的外部標(biāo)識(shí)符。對(duì)于只產(chǎn)生一個(gè)單一目標(biāo)模塊的匯編語言程序,它所訪問的所有標(biāo)識(shí)符必須是局部定義的,對(duì)于多模塊程序來說,必須給匯編程序一個(gè)信息以說明其間的有些標(biāo)識(shí)符是外部的,而不致被匯編程序把它們處理為一些無效的標(biāo)識(shí)符。此外,為了允許其它模塊訪問一給定模塊中的標(biāo)識(shí)符,該給定模塊必須包含一個(gè)標(biāo)識(shí)符清單以說明其中的標(biāo)識(shí)符可為其它模塊訪問。因此,每個(gè)模塊可含有兩個(gè)清單:一個(gè)清單標(biāo)明它所要訪問的其它模塊的標(biāo)識(shí)符;另一個(gè)清單是列出它所定義的,且為其它模塊所訪問的標(biāo)識(shí)符。這兩個(gè)清單依靠偽指令EXTRN和PUBLIC列出。EXTRN和PUBLIC偽指令語句的格式如下:EXTRN標(biāo)識(shí)符:類型,…,標(biāo)識(shí)符:類型PUBLIC標(biāo)識(shí)符,…,標(biāo)識(shí)符EXTRN偽指令語句中的標(biāo)識(shí)符表示是外部的變量或標(biāo)號(hào),而PUBLIC偽指令語句中的標(biāo)識(shí)符表示可供其它模塊引用的變量或標(biāo)號(hào)。在EXTRN偽指令中,若標(biāo)識(shí)符為標(biāo)號(hào),則類型有NEAR或FAR;若標(biāo)識(shí)符為變量,則類型有BYTE,WORD或DWORD。在語句INCVAR1中,若VAR1是外部變量,且對(duì)應(yīng)于一個(gè)字,則含有該語句的模塊中就必須有如下所示的一條偽指令語句:EXTRN…,VAR1:WORD,…而在定義VAR1模塊中就必須含有下列語句:PUBLIC,…,VAR1,…

14.源程序結(jié)束偽指令END偽指令END用來表明END語句處是源程序的終結(jié)。其格式如下:END表達(dá)式這里的表達(dá)式通常就是程序第一條指令的語句標(biāo)號(hào)。這樣,程序在匯編、連接后,將目標(biāo)代碼裝入內(nèi)存之后準(zhǔn)備要執(zhí)行的起始地址由此標(biāo)號(hào)所決定。當(dāng)然,這個(gè)表達(dá)式也可以省去。下面是一個(gè)完整的源程序片斷,從中可以看出END偽指令的用法:DATASEGSEGMENTVAR1DW7654HVAR2DW2345HRESULTDW?DATA-SEGENDSCODE-SEGSEGMENTASSUMECS:CODESEG,DS:DATA-SEGSTART:MOVAX,DATA-SEGMOVDS,AXMOVAX,VAR1SUBAX,VAR2MOVRESULT,AXCODE-SEGENDSENDSTART15.常用偽指令列表表6.4MASM偽操作符表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表6.1.6宏指令及其使用1.宏指令、宏定義和宏調(diào)用宏指令是源程序中具有獨(dú)立功能的一段程序代碼。它可以根據(jù)用戶的需要,由用戶自己在源程序中定義。宏指令一經(jīng)定義,便可在以后的程序中多次調(diào)用。宏定義由MASM宏匯編程序提供的偽指令實(shí)現(xiàn),格式為宏指令名MACRO〈形式參數(shù)〉;…;ENDM宏體其中MACRO和ENDM均為偽指令,它們必須成對(duì)出現(xiàn)在源程序中,且必須以MACRO作為宏定義的開頭,而以ENDM作為宏定義的結(jié)尾。MACRO和ENDM之間為宏體,是實(shí)現(xiàn)宏指令功能的實(shí)體。宏指令名(Macroname)是為宏指令起的名字,以供在源程序中調(diào)用該宏指令時(shí)用。形式參數(shù)(也稱虛擬參數(shù))的設(shè)置增強(qiáng)了宏指令的功能,使其更加靈活。形式參數(shù)的設(shè)置可根據(jù)需要而定,可用一個(gè)或多個(gè)(最多不超過132個(gè)),也可以沒有。當(dāng)有多個(gè)形式參數(shù)時(shí),參數(shù)之間必須以逗號(hào)隔開。宏調(diào)用的格式為宏指令名〈實(shí)際參數(shù)〉例6.1設(shè)有如下4個(gè)宏定義:PUSHREGMACROPUSHAXPUSHBXPUSHCXPUSHDXPUSHSIPUSHDIENDM顯而易見,這是一個(gè)無形式參數(shù)的宏定義。LOADWMACROPR,VAR MOVPR,VAR MOVAX,[PR] ENDM該宏定義有2個(gè)形式參數(shù),它們都在操作數(shù)域,互相之間必須用逗號(hào)分開。SHIFTMACRON,REG,CCMOVCL,NS&CCREG,CLENDM根據(jù)以上宏定義,若需編一段程序,將某變量WVAR內(nèi)容送AX寄存器,右移4位后,再存入WVAR變量處,則可采用宏調(diào)用方法編寫如下程序段:LOADWSI,WVARSHIFT4,AX,ARSAVEWSI,AX,INC……相應(yīng)的宏展開如下:

LOADWSI,WVAR+MOVSI,WVAR+MOVAX,[SI]SHIFT4,AX,AR+MOVCL,4+SARAX,CLSAVEWSI,AX,INC+MOV[SI],AX+INCSI……宏展開時(shí),匯編程序在所展開的指令前加“+”,以便與其它指令區(qū)別。上述宏展開中LOADWSI,WVAR語句、SHIFT4,AX,AR語句及SAVEWSI,AX,INC語句是為程序閱讀方便而提供的,不占內(nèi)存單元。又若需將變量FIRST的內(nèi)容取入BX,左移4位后再存入FIRST變量處,則有如下程序段:LOADWDI,FIRSTMOVBX,AXSHIFT4,BX,ALSAVEWDI,BX,INC……宏展開后程序段如下:

+LOADWDI,FIRST+MOV DI,FIRST+MOV AX,[DI]MOV BX,AXSHIFT 4,BX,AL+MOV CL,4+SAL BX,CL+SAVEWDI,BX,INC+MOV DI],BX+INC DI……2.宏嵌套宏定義中允許使用宏調(diào)用,但所調(diào)用的宏指令必須先定義過。不僅如此,宏定義中還可以包含宏定義。例6.2設(shè)計(jì)一個(gè)程序段實(shí)現(xiàn)下列運(yùn)算:FIRST1*FIRST2+SECOND1*SECOND2并將結(jié)果存儲(chǔ)起來(不考慮最后結(jié)果溢出)。MULTIPLYMACROOPR1,OPR2,RESULT MOVAL,OPR1 IMULOPR2 MOVRESULT,AX ENDMADDMULTMACROREG,VAR1,VAR2 MULTIPLYFIRST1,FIRST2,MULT1 MULTIPLYSECOND1,SECOND2,MULT2 MOVREG,VAR1 ADDREG,VAR2 MOVSUM,REG ENDM

可以看出,在ADDMULT宏定義中兩次調(diào)用了定義過的宏指令MULTIPLY。若有宏調(diào)用:ADDMULTAX,MULT1,MULT2則宏展開后的程序段如下:

MULTIPLYFIRST1,FIRST2,MULT1+MOV AL,FIRST1+IMULFIRST2+MOVMULT1,AXMULTIPLYSECOND1,SECOND2,MULT2+MOVAL,SECOND1+IMULSECOND2+MOVMULT2,AXADDMULTAX,MULT1,MULT2+MOVAX,MULT1+ADDAX,MULT2+MOVSUM,AX……例6.3采用宏定義體內(nèi)包含宏定義的方法設(shè)計(jì)一個(gè)運(yùn)算宏指令。宏定義:DEFCALCUMACROCALCULATION,OPERATORCALCULATIONMACROX,Y,Z PUSHAX MOVAX,X OPERATORAX,Y MOVZ,AX POPAX ENDM ENDMDEFCALCU宏指令定義體內(nèi)包含了一個(gè)宏定義CALCULATION。并且,內(nèi)層宏定義的宏指令名CALCULATION又是外層宏定義的形式參數(shù)。由于CALCULATION宏指令的定義包含在DEFCALCU宏指令的定義體內(nèi),要調(diào)用CALCULATION宏指令,必須先調(diào)用DEFCALCU宏指令,以便使CALCULATION宏指令先得到定義,即需按如下步驟進(jìn)行:宏調(diào)用DEFCALCUADDITION,ADD宏展開+ADDITIONMACROX,Y,Z PUSHAXMOVAX,XADDAX,YMOVZ,AXPOPAXENDM

得到宏指令A(yù)DDITION的宏定義。這樣便可有宏調(diào)用:ADDITIONFIRST,SECOND,SUM并有宏展開:+PUSHAX+MOVAX,FIRST+ADDAX,SECOND+MOVSUM,AX+POPAX對(duì)于宏指令DEFCALCU宏定義體中的形式參數(shù)CALCULATION及OPERATOR給予不同的實(shí)際參數(shù)去取代,便會(huì)得到不同的運(yùn)算宏指令,如宏調(diào)用

DEFCALCUSUBTRACT,SUB可形成減法的宏定義;宏調(diào)用

DEFCALCULOGAND,AND可形成邏輯與的宏定義等。

3.宏定義中的標(biāo)號(hào)與變量如果宏定義體中出現(xiàn)標(biāo)號(hào)或變量,該宏指令又需要被多次調(diào)用,這樣宏展開后程序中將會(huì)多次重復(fù)出現(xiàn)相同的標(biāo)號(hào)或變量,也就是說會(huì)產(chǎn)生重復(fù)定義標(biāo)號(hào)或變量的錯(cuò)誤,這是不允許的。MASM宏匯編程序解決這一問題的方法是在宏定義中用偽指令LOCAL把要出現(xiàn)在宏體中的標(biāo)號(hào)或變量定義成局部標(biāo)號(hào)或變量。LOCAL偽指令定義局部標(biāo)號(hào)或變量的格式為L(zhǎng)OCAL參數(shù)表其中參數(shù)表是指宏體中要用到的標(biāo)號(hào)或變量。該

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論