qA匯編語言源程序的框架結(jié)構(gòu)課件_第1頁
qA匯編語言源程序的框架結(jié)構(gòu)課件_第2頁
qA匯編語言源程序的框架結(jié)構(gòu)課件_第3頁
qA匯編語言源程序的框架結(jié)構(gòu)課件_第4頁
qA匯編語言源程序的框架結(jié)構(gòu)課件_第5頁
已閱讀5頁,還剩129頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

§5.1匯編語言源程序的框架結(jié)構(gòu)

編制匯編語言源程序時,首先要使用段定義偽指令和段尋址偽指令來構(gòu)造一個由若干指令和數(shù)據(jù)組成的程序。構(gòu)造一個源程序的框架結(jié)構(gòu)有如下兩種格式:第一種格式:……MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND BEGIN第5章8086/8088匯編語言程序設(shè)計§5.1匯編語言源程序的框架結(jié)構(gòu)第5章8086/801第二種格式:…… RET ;取程序段前綴首地址MAIN ENDPCODE ENDSEND BEGIN區(qū)別:兩種格式的本質(zhì)區(qū)別在于返回DOS的方法不同:對于第一種格式,采用了調(diào)用DOS系統(tǒng)的4CH功能,返回DOS。具體方法是:在要返回DOS處,安排如下兩條指令:MOV AH,4CHINT 21H對于第二格式,DOS返回方法是調(diào)用20H類型的中斷服務(wù)程序。

第二種格式:2§5.2順序結(jié)構(gòu)程序設(shè)計順序程序結(jié)構(gòu)是指完全按照順序逐條執(zhí)行的指令序列,這種結(jié)構(gòu)的流程圖除了有一個開始框和結(jié)束框外,就是若干處理框,沒有判斷框,如圖5.1所示。圖5.1順序程序的結(jié)構(gòu)形式

§5.2順序結(jié)構(gòu)程序設(shè)計3例5.1:試分別用匯編語言源程序的兩種框架結(jié)構(gòu)編制程序,求出表達(dá)式:(X×4-Y)/2的值,并保存到RESULT存儲單元中,其中X,Y均為字節(jié)變量。解:完成該功能的流程圖如圖5.2所示:圖5.2例5.1的功能實現(xiàn)流程圖例5.1:試分別用匯編語言源程序的兩種框架結(jié)構(gòu)編制程序,求出4參考程序1:DATA SEGMENT ;數(shù)據(jù)段X DB 2Y DB 4Z DB ? ;定義變量DATA ENDSSTACK SEGMENT PARA STACKDW 20H DUP(0)STACK ENDSCODE SEGMENT ;代碼段ASSUMECS:CODE,DS:DATA,SS:STACK參考程序1:5BEGIN: MOV AX,DATAMOV DS,AX ;DS賦初值MOV AL,X ;AL←XMOV CL,2SAL AL,CL ;AL←X×4SUB AL,Y ;AL←X×4-YSAR AL,1 ;AL←(X×4-Y)/2MOV Z,AL ;存結(jié)果MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND BEGINBEGIN: MOV AX,DATA6參考程序2:DATA SEGMENTX DB 2Y DB 4Z DB ?DATA ENDSSTACK SEGMENT PARA STACKDW 20H DUP(0)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKPROC1 PROC FAR ;使RET為遠(yuǎn)返回END BEGIN參考程序2:7BEGIN: PUSH DS ;入棧保存地址MOV AX,0 ;程序段前綴的首地址PUSH AXMOV AX,DATAMOV DS,AXMOV AL,X ;AL←XMOV CL,2SAL AL,CL ;AL←X×4SUB AL,Y ;AL←X×4-YSAR AL,1 ;AL←(X×4-Y)/2MOV Z,AL ;存結(jié)果RET ;取程序段前綴首地址BEGIN: PUSH DS ;入棧保存地址8PROC1 ENDPCODE ENDS§5.3分支結(jié)構(gòu)程序設(shè)計分支程序結(jié)構(gòu)可以有兩種形式,如圖5.4所示,它們分別相當(dāng)于高級語言程序中的IF-THEN-ELSE語句和CASE語句,它們適用于要根據(jù)不同條件做不同處理的情況。PROC1 ENDP§5.3分支結(jié)構(gòu)程序設(shè)計9§5.3.1用比較/測試的方法實現(xiàn)IF-THEN-ELSE結(jié)構(gòu)實現(xiàn)方法:在產(chǎn)生分支之前,通常用比較、測試的辦法在標(biāo)志寄存器中設(shè)置相應(yīng)的標(biāo)志位,然后再選用適當(dāng)?shù)臈l件轉(zhuǎn)移指令,以實現(xiàn)不同情況的分支轉(zhuǎn)移。(1)進(jìn)行比較,使用比較指令:CMP DEST,SRC該指令進(jìn)行減法操作,而不保存結(jié)果,只設(shè)置標(biāo)志位。(2)進(jìn)行測試,使用測試指令TEST DEST,SRC該指令進(jìn)行邏輯與操作,而不保存結(jié)果,只設(shè)置標(biāo)志位。§5.3.1用比較/測試的方法實現(xiàn)IF-THEN-ELS10§5.3.2用地址表法實現(xiàn)CASE結(jié)構(gòu)(即多路分支)用地址表法實現(xiàn)CASE結(jié)構(gòu)的基本思路是:將各分支程序的入口地址依次羅列形成一個地址表,讓BX指向地址表的首地址,從鍵盤接收或其他方式獲取要轉(zhuǎn)到的分支號,再讓BX與分支號進(jìn)行運算,使BX指向?qū)?yīng)分支入口地址,最后即可使用JMPWORDPTR[BX]或JMPDWORDPTR[BX]指令實現(xiàn)所要轉(zhuǎn)到的分支;程序設(shè)計流程圖如圖5.6所示:§5.3.2用地址表法實現(xiàn)CASE結(jié)構(gòu)(即多路分支)11圖5.6用地址表法實現(xiàn)多路分支的結(jié)構(gòu)框圖例5.4:編程實現(xiàn)菜單選擇,根據(jù)不同的選擇做不同的事情。

解:假設(shè)有3路分支,在地址表中的入口地址分別:A0、A1、A2;具體見圖5.7所示:

圖5.6用地址表法實現(xiàn)多路分支的結(jié)構(gòu)框圖例5.4:編程12參考程序:DATA SEGMENTMENU DB 0DH,0AH,"0:Chinese!"DB 0DH,0AH,"1:English!"DB 0DH,0AH,"2:German!"DB 0DH,0AH,"Pleasechooseonetoanswerthefollowingquestion:$"ER DB0DH,0AH,"Iamsorry,youchoosethemistake!$"參考程序:13S0 DB 0DH,0AH,"OK,PleaseanswerinChinese!$"S1 DB 0DH,0AH,"OK,PleaseanswerinEnglish!$"S2 DB 0DH,0AH,"OK,PleaseanswerinGerman!$"TAB DW A0,A1,A2 ;地址表DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXLEA DX,MENU ;顯示菜單MOV AH,9INT 21HS0 DB 0DH,0AH,"OK,Pleaseanswe14MOV AH,1 ;1號DOS功能調(diào)用,接收分支號INT 21HCMP AL,'0' ;進(jìn)行合法判斷JB ERRORCMP AL,'2'JA ERRORLEA BX,TAB ;取地址表首址SUB AL,30HSHL AL,1 ;段內(nèi)轉(zhuǎn)移乘以2,段間轉(zhuǎn)移乘以4XOR AH,AH ;AH清零ADD BX,AXJMP WORDPTR[BX] ;產(chǎn)生多分支轉(zhuǎn)移MOV AH,1 ;1號DOS功能調(diào)用,接收分支號15A0: LEA DX,S0 ;各分支程序段MOV AH,9INT 21HJMP EXIT1A1: LEA DX,S1MOV AH,9INT 21HJMP EXIT1A2: LEA DX,S2MOV AH,9INT 21HJMP EXIT1A0: LEA DX,S0 ;各分支程序段16ERROR: MOV DX,OFFSETERMOV AH,9INT 21HEXIT1: MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND START§5.3.3用轉(zhuǎn)移表法實現(xiàn)CASE結(jié)構(gòu)(即多路分支)用轉(zhuǎn)移表法實現(xiàn)CASE結(jié)構(gòu)的基本思路:將轉(zhuǎn)到各分支程序的轉(zhuǎn)移指令依次羅列形成一個轉(zhuǎn)移表,讓BX指向轉(zhuǎn)移表的首地址,從鍵盤接收或其他方式獲取要轉(zhuǎn)到的分支號,再讓BX與分支號進(jìn)行運算,使BX指向?qū)?yīng)轉(zhuǎn)移表中轉(zhuǎn)到該分支的轉(zhuǎn)移指令處,最后即可使用JMPBX指令實現(xiàn)所要轉(zhuǎn)到的分支;具體見圖5.8所示:ERROR: MOV DX,OFFSETER§5.3.317圖5.8用轉(zhuǎn)移表法實現(xiàn)多路分支的結(jié)構(gòu)框圖例5.5:編程實現(xiàn)菜單選擇,根據(jù)不同的選擇做不同的事情。解:假設(shè)有3路分支,轉(zhuǎn)移表中的轉(zhuǎn)移指令分別為:JMPSHORTA0、JMPSHORTA1、JMPSHORTA2;具體見圖5.9所示:圖5.8用轉(zhuǎn)移表法實現(xiàn)多路分支的結(jié)構(gòu)框圖18參考程序:DATA SEGMENTMENU DB 0DH,0AH,"0:Chinese!"DB 0DH,0AH,"1:English!"DB 0DH,0AH,"2:German!"DB 0DH,0AH,"Pleasechooseonetoanswerthefollowingquestion:$"參考程序:19ER DB0DH,0AH,"Iamsorry,youshoosethemistake!$"S0 DB 0DH,0AH,"OK,PleaseanswerinChinese!$"S1 DB 0DH,0AH,"OK,PleaseanswerinEnglish!$"S2 DB 0DH,0AH,"OK,PleaseanswerinGerman!$"DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXLEA DX,MENU ;顯示菜單MOV AH,9INT 21HER DB0DH,0AH,"Iamsorry,yo20MOV AH,1 ;1號DOS功能調(diào)用,接收分支號INT 21HCMP AL,'0'JB ERRORCMP AL,'2'JA ERRORLEA BX,TAB ;取地址表首址SUB AL,30HSHL AL,1 ;短轉(zhuǎn)移乘以2,近轉(zhuǎn)移乘以3,遠(yuǎn)轉(zhuǎn)移乘以5XOR AH,AH ;AH清零ADD BX,AXMOV AH,1 ;1號DOS功能調(diào)用,接收分支號21JMP BX ;產(chǎn)生多分支轉(zhuǎn)移TAB: JMP SHORT A0 ;轉(zhuǎn)移表JMP SHORT A1JMP SHORT A2A0: LEA DX,S0 ;各分支程序段MOV AH,9INT 21HJMP EXIT1A1: LEA DX,S1MOV AH,9INT 21HJMP BX ;產(chǎn)生多分支轉(zhuǎn)移22JMP EXIT1A2:LEA DX,S2MOV AH,9INT 21HJMP EXIT1ERROR: MOV DX,OFFSETERMOV AH,9INT 21HEXIT1: MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND STARTJMP EXIT123§5.4循環(huán)結(jié)構(gòu)程序設(shè)計

§5.4.1循環(huán)程序的組成1.設(shè)置循環(huán)的初始狀態(tài)如置循環(huán)次數(shù)的計數(shù)值,以及為循環(huán)體正常工作的初始狀態(tài)等;2.循環(huán)體這是循環(huán)的工作主體,它由循環(huán)的工作部分及修改部分組成。3.循環(huán)控制部分它是循環(huán)程序設(shè)計的關(guān)鍵,每一個循環(huán)程序必須選擇一個循環(huán)控制條件來控制循環(huán)的運行和結(jié)束,通常有兩種方法控制循環(huán):用計數(shù)控制循環(huán),用條件控制循環(huán)

§5.4循環(huán)結(jié)構(gòu)程序設(shè)計24§5.4.2循環(huán)程序的結(jié)構(gòu)形式循環(huán)程序有兩種結(jié)構(gòu),一種是DO-WHILE結(jié)構(gòu)形式,另一種是DO-UNTIL結(jié)構(gòu)形式。具體見圖5.10所示:DO-WHILE結(jié)構(gòu)把對循環(huán)控制條件的判斷放在循環(huán)的入口,先判斷條件,滿足條件就執(zhí)行循環(huán)體,否則退出循環(huán)。DO-UNTIL結(jié)構(gòu)是先執(zhí)行循環(huán)體然后再判斷控制條件,不滿足條件則繼續(xù)執(zhí)行循環(huán)操作,一旦滿足條件則退出循環(huán)。一般講,如果循環(huán)次數(shù)等于0的可能,則應(yīng)選擇DO-WHILE結(jié)構(gòu),否則用DO-UNTIL結(jié)構(gòu)。圖5.10循環(huán)程序的結(jié)構(gòu)形式

§5.4.2循環(huán)程序的結(jié)構(gòu)形式圖5.10循環(huán)程序的結(jié)25§5.4.3循環(huán)控制的方法

1.用計數(shù)控制循環(huán)這種方法直觀、方便,易于程序設(shè)計。只要在編制程序時,循環(huán)次數(shù)已知,就可以使用這種方法設(shè)計循環(huán)程序。然而更多的循環(huán)程序,在編制程序時并不能確切知道循環(huán)次數(shù),但是知道循環(huán)次數(shù)是前面運算或操作的結(jié)果或者被存放在某內(nèi)存單元中。例5.6:試編制程序統(tǒng)計字節(jié)變量VAR中1的個數(shù),并將它存入COUNT單元中。

解:要測試出VAR中1的個數(shù)就應(yīng)該逐位進(jìn)行測試,可根據(jù)最低位是否為1來計數(shù),然后用移位的辦法把各位數(shù)逐次移到最低位去,共需要測試8次。程序流程如圖5.11所示:§5.4.3循環(huán)控制的方法例5.6:試編制程序統(tǒng)計字節(jié)變26圖5.11例5.6的功能實現(xiàn)流程圖

圖5.11例5.6的功能實現(xiàn)流程圖27參考程序:DATA SEGMENTVAR DB37HCOUNT DB?DATA ENDSCODE SEGMENTASSUMECS:CODE,DS:DATABEGIN: MOV AX,DATAMOV DS,AXMOV AL,VAR ;AL←VAR的值MOV CX,8 ;賦循環(huán)初值XOR BL,BL ;賦計數(shù)器初值參考程序:28LL: TEST AL,1 ;測試AL的最低位JZ LL1 ;最低位為0轉(zhuǎn)LL1INC BL ;計數(shù)器加1LL1: SHR AL,1 ;邏輯右移1位LOOP LL ;循環(huán)控制MOV COUNT,BL ;COUNT←計數(shù)器BL的值MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND BEGINLL: TEST AL,1 ;測試AL的最低位292.用條件控制循環(huán)

例5.8:將正整數(shù)NUM插入到一個從小到大排列好順序的正整數(shù)字節(jié)數(shù)組序列中。

分析:假設(shè)該數(shù)組的首地址和末地址分別為ARRAY_HEAD、ARRAY_END,顯然在這里需要插入的是一個數(shù),所以不一定要掃描整個數(shù)組。同時為了插入這個數(shù)據(jù),必須要空出位置,即凡是比它大的數(shù)據(jù)都應(yīng)該向地址增大的方向移動一個字節(jié),故應(yīng)該從數(shù)組的尾部向頭部查找,可逐字節(jié)取出比較。值得注意的是,應(yīng)該考慮正整數(shù)NUM大于或小于數(shù)組中的所有數(shù)的可能,即如果NUM大于數(shù)組中所有數(shù),則第一次比較就可以結(jié)束查找;如果NUM小于數(shù)組中所有數(shù),則必須及時結(jié)束查找,絕對不允許查找的范圍超出數(shù)組的首地址,當(dāng)然可以把數(shù)組的首地址或循環(huán)次數(shù)作為結(jié)束查找的條件。根據(jù)上述分析,可以得出程序流程如圖5.13所示:2.用條件控制循環(huán)例5.8:將正整數(shù)NUM插入到一30圖5.13例5.8的功能實現(xiàn)流程圖

圖5.13例5.8的功能實現(xiàn)流程圖31參考程序:NUM EQU 36HDATA SEGMENTARRAY DB 12H,24H,48H,60H,72H,84HY DB ?DATA ENDSCODE SEGMENTASSUMECS:CODE,DS:DATABEGIN: MOV AX,DATAMOV DS,AXMOV CX,Y-ARRAY ;循環(huán)次數(shù)初始化MOV AL,NUM ;插入值送AL參考程序:32LEA SI,YDEC SI;取得ARRAY的最后元素的偏移地址LOP: CMP ARRAY[SI],AL ;比較JLE INSERTMOV AH,ARRAY[SI]MOV ARRAY[SI+1],AH ;數(shù)據(jù)交換DEC SI ;修改偏移地址LOOP LOPINSERT: MOV ARRAY[SI+1],AL ;插入數(shù)據(jù)MOV AH,4CHLEA SI,Y33

INT 21HCODE ENDSEND BEGIN§5.5子程序設(shè)計

§5.5.1子程序的構(gòu)造前面我們學(xué)習(xí)了過程定義偽指令,我們也就是用它們來構(gòu)成的子程序,其格式為:子程序名 PROC (NEAR/FAR)保存信息……恢復(fù)信息RET子程序名 ENDPINT 21H§5.5子34§5.5.2子程序的調(diào)用與返回子程序的正確執(zhí)行是由子程序的正確調(diào)用和返回保證的。IBMPC機的CALL和RET指令就分別完成了子程序的調(diào)用和返回功能。1.調(diào)用指令:CALL過程名執(zhí)行CALL指令,首先保留斷點地址于堆棧中,然后轉(zhuǎn)移到目標(biāo)單元,它對PSW無影響。2.返回指令:RET一個子程序執(zhí)行的最后一條指令必定是返回指令RET,用以返回到調(diào)用子程序的斷點處。但在位置上并不一定就是是最后一條指令。它的位置靈活,并不是必須要在最后。只是習(xí)慣上我們通常將它置于子程序的最后。

§5.5.2子程序的調(diào)用與返回35§5.5.3編制子程序的要求1.子程序必須具有通用性2.注意保存信息和恢復(fù)信息要注意最先壓入堆棧的應(yīng)該最后彈出來,值得注意的是:必須搞清楚那些寄存器是必須保存的,那些又是不必要或不應(yīng)該保存的。一般來說,子程序中用到的寄存器是應(yīng)該保存的,但是如果主程序和子程序之間使用寄存器傳遞參數(shù)的話,該寄存器則不一定需要保存,特別是用來向主程序回送結(jié)果(即出口參數(shù))的寄存器,則更不應(yīng)該因保存和恢復(fù)該寄存器的內(nèi)容而破壞了應(yīng)該向主程序傳送的信息。3.選用適當(dāng)?shù)姆椒ㄔ谧映绦蚝椭鞒绦蛑g的進(jìn)行參數(shù)傳遞§5.5.3編制子程序的要求36這種主程序與子程序之間的信息傳送稱為參數(shù)傳遞,它可以有以下三種:①用寄存器傳遞參數(shù)這是最常用的一種方式,通常在參量不多的時候使用這種方法。②用地址表傳遞參數(shù)

通過地址表傳送參數(shù)的方法是在主程序中首先建立一個地址表,把要傳送給子程序的參數(shù)都存放在地址表中,然后把地址表的首地址通過寄存器傳送到子程序中去;最后子程序通過地址表取得所需參數(shù)。

③用堆棧傳遞參數(shù)這種方法是在主程序中把要傳送給子程序的參數(shù)先保存到堆棧中,然后子程序再從堆棧中取出參數(shù)以達(dá)到傳送參數(shù)的目的。

這種主程序與子程序之間的信息傳送稱為參數(shù)傳遞,它可以有以37§5.6高級匯編語言技術(shù)

§5.6.1宏匯編1.宏定義宏在使用前必須先進(jìn)行宏定義。宏定義格式為:宏指令名 MACRO 形式參數(shù),形式參數(shù),… <宏體> ENDM其中,宏指令名:宏定義的名字(即給宏體中程序段指定一個符號名),不可缺省,宏調(diào)用時要使用它,第一個符號必須是字母,其后可以是字母或數(shù)字§5.6高級匯編語言技術(shù)38MACRO…ENDM:宏定義偽指令助記符,不可缺省。它們成對出現(xiàn),表示宏定義的開始和結(jié)束,ENDM前不帶宏指令名。宏體:一段有獨立功能的程序代碼段。形式參數(shù):又稱啞元,各個啞元之間用逗號隔開,可以缺省。2.宏調(diào)用經(jīng)宏定義后的宏指令可以在源程序中調(diào)用,宏調(diào)用格式為:宏指令名 實參,實參…宏調(diào)用只需要有宏指令名,若宏定義中有形參,那么宏調(diào)用時必須帶有實際參數(shù)來替代形參,實際參數(shù)的個數(shù),順序,類型與形參一一對應(yīng),各個實參之間用逗號分開。原則上實參的個數(shù)與形參的個數(shù)相等,但匯編程序不要求它們必須相等,若實參個數(shù)大于形參個數(shù),則多余的實參不予考慮,若實參個數(shù)小于形參個數(shù),則多余的形參作“空”處理。

MACRO…ENDM:宏定義偽指令助記符,不可缺省。它們成對393.宏展開匯編程序在對源程序匯編時,對每個宏調(diào)用作宏展開,每條插入的宏體指令前帶上加號“+”。例5.11:不帶參數(shù)的宏定義,用宏指令來實現(xiàn)回車換行。宏定義:CRLF MACROMOV DL,0DH ;回車MOV AH,2INT 21HMOV DL,0AH ;換行MOV AH,23.宏展開例5.11:不帶參數(shù)的宏定義,用宏指令來實現(xiàn)回車換40INT 21H ENDM宏調(diào)用:CRLF宏展開:將下述程序段替換宏調(diào)用語句。+MOV DL,0DH ;回車+MOV AH,2+I(xiàn)NT 21H+MOV DL,0AH ;換行+MOV AH,2+I(xiàn)NT 21HINT 21H414.宏調(diào)用中參數(shù)傳遞宏定義中的參數(shù)可以有多個,實參可以是數(shù)字,寄存器或操作碼。宏定義還可用部分操作碼作參數(shù),但在宏定義中必須用“&”作分隔符,&是一個操作符,它在宏定義體中可作為啞元的前綴,宏展開時,可以把&前后兩個符號合并成一個符號。例5.12:宏定義帶一個參數(shù),用宏指令實現(xiàn)將AX中內(nèi)容右移任意次(小于256)。

宏定義:SHIFT MACRO N MOV CL,N SAL AX,CL ENDM宏調(diào)用1: SHIFT 44.宏調(diào)用中參數(shù)傳遞例5.12:宏定義帶一個參數(shù),用宏指令實42宏調(diào)用2: SHIFT 8宏展開1: MOV CL,4 ;AX中內(nèi)容算術(shù)左移4次 SAL AX,CL宏展開2: MOV CL,8 ;AX中內(nèi)容算術(shù)左移8次 SAL AX,CL5.宏定義嵌套在宏定義中允許使用宏調(diào)用,但必須先定義后調(diào)用。

例5.14:宏定義:AD1 MACRO M,N MOV BX,M

宏調(diào)用2: SHIFT 85.宏定義嵌套例5.14:43ADD AX,NENDMAD1M MACRO R1,R2,R3PUSH AXPUSH BXAD1 R1,R2MOV X3,AXPOP BXPOP AXENDM宏調(diào)用: AD1M CX,BX,DX宏展開: PUSH AXADD AX,N44PUSH BXAD1 R1,R2 ;此語句不占內(nèi)存MOV BX,CX ;AD1宏定義展開ADD AX,BXMOV DX,AXPOP BXPOP AX6.取消宏定義語句格式為:PURGE宏指令名,宏指令名…PURGE:偽指令助記符,不可缺省,因為經(jīng)過定義的宏指令名,不允許重新定義,必須用PURGE語句將其取消后,才能重新定義,此語句一次可以取消多個宏指令名。PUSH BX6.取消宏定義語句45

7.宏指令與子程序的區(qū)別⑴過程調(diào)用使用CALL語句,由CPU執(zhí)行,宏指令調(diào)用由宏匯編程序MASM中宏處理程序來識別。⑵過程調(diào)用時,每調(diào)用一次都要保留程序的斷點和保護(hù)現(xiàn)場,返回時要恢復(fù)現(xiàn)場和恢復(fù)斷點,增加了操作時間,執(zhí)行速度慢。而宏指令調(diào)用時,不需要這些入棧及出棧操作,執(zhí)行速度較快。⑶過程調(diào)用的子程序與主程序分開獨立存在,經(jīng)匯編后在存儲器中只占有一個子程序段的空間,主程序轉(zhuǎn)入此處運行,因此目標(biāo)代碼長度短,節(jié)省內(nèi)存空間。而宏調(diào)用是在匯編過程中展開,宏調(diào)用多少次,就插入多少次,因此目標(biāo)代碼長度大,占內(nèi)存空間多;⑷一個子程序設(shè)計,一般完成某一個功能,多次調(diào)用完成相同操作,僅入口參數(shù)可以改變,而宏指令可以帶啞元,調(diào)用時可以用實元取代,使不同的調(diào)用完成不同的操作,增加使用的靈活性。

7.宏指令與子程序的區(qū)別46§5.6.2重復(fù)匯編重復(fù)匯編偽指令語句有以下三種:1.定重復(fù)格式:REPT 表達(dá)式宏體ENDM其中,REPT…ENDM:偽指令助記符,必須成對出現(xiàn),不可省略。宏體:表示需要重復(fù)的語句序列。表達(dá)式:表示重復(fù)次數(shù)。§5.6.2重復(fù)匯編47例5.16:將2、4、8、16、32分配給連續(xù)的5個存儲單元。 NUM=1REPT5 NUM=NUM*2 DBNUM

ENDM匯編后: +DB2 +DB4 +DB8 +DB16 +DB32例5.16:將2、4、8、16、32分配給連續(xù)的5個存儲單元482.不定重復(fù)格式:IRP 形參,<實參表> 宏體ENDM其中,IRP…ENDM:偽指令助記符,必須成對出現(xiàn),不可省略。宏體:要重復(fù)的語句序列,重復(fù)次數(shù)由參數(shù)個數(shù)決定。實數(shù)表中是每次重復(fù)時將要取的實參,實參之間用逗號隔開,實參表用尖括號<>括起來。每次重復(fù),依次取實參表中一項,代入語句序列中啞元。前面將2、4、8、16、32分配給連續(xù)的5個存儲單元的例子也可以用如下不定重復(fù)偽指令:IRP NUM,<2,4,8,16,32> DB NUM ENDM2.不定重復(fù)49例5.17:若要把AX,BX,CX,DX的內(nèi)容壓入堆棧,則可以用如下不定重復(fù)偽指令:IRP REG,<AX,BX,CX,DX> PUSH REG ENDM匯編后展開為以下四條指令: +PUSH AX +PUSH BX +PUSH CX +PUSH DX例5.17:若要把AX,BX,CX,DX的內(nèi)容壓入堆棧,則可503.不定重復(fù)字符格式為:IRPC 形式參數(shù),字符串 宏體 ENDM其中,IRPC..ENDM:偽指令助記符,必須成對出現(xiàn),不可省略。宏體:重復(fù)執(zhí)行的語句序列,每次重復(fù)時依次用字符串中字符代替形式參數(shù),重復(fù)次數(shù)取決于字符串中字符的個數(shù)。字符串:可用尖括號也可不用尖括號括起來。例5.18:若要從堆棧中彈出4個字,分別送入DX,CX,BX,AX,則可用如下不定重復(fù)字符偽指令:IRPC REG,<DCBA> POP REG&X ENDM3.不定重復(fù)字符例5.18:若要從堆棧中51匯編后展開為以下四條指令: +POP DX +POP CX +POP BX +POP AX§5.6.3條件匯編條件匯編是對給定的條件進(jìn)行測試,匯編程序根據(jù)測試結(jié)果,將一段程序嵌入源程序匯編或不進(jìn)行匯編,它的一般格式為:IF×× 表達(dá)式 指令體1 ;條件為真匯編指令體1ELSE 指令體2 ;條件為假匯編指令體2ENDIF匯編后展開為以下四條指令:§5.6.3條件匯編52其中,IF××…ENDIF:條件匯編偽指令助記符,必須成對出現(xiàn),不可省略。IF語句后的“××”是指定的條件。如果“IF××”指定的條件為真時則宏匯編程序?qū)⒅噶铙w1中的語句匯編成相應(yīng)的目標(biāo)代碼,否則就把指令體2中的語句匯編成相應(yīng)的目標(biāo)代碼。ELSE:是任選部分,如果沒有ELSE,那么“IF××”指定的條件滿足就匯編,否則就不匯編。“IF××”條件匯編的形式見表5.1所示:其中,IF××…ENDIF:條件匯編偽指令助記符,必須成對出53例5.20:利用條件匯編偽指令,可以根據(jù)不同情況,產(chǎn)生無條件轉(zhuǎn)移指令如JMP,或產(chǎn)生條件轉(zhuǎn)移指令如JE、JNE、JB、JNB等。宏定義:GOTO MACRO LOP,X,REL,YIFB <REL>JMP LOPELSEMOV AL,XCMP AL,YJ&REL LOPENDIFENDM例5.20:利用條件匯編偽指令,可以根據(jù)不同情況,產(chǎn)生無條件54宏調(diào)用: ……GOTO LOP1,VAR1,E,VAR2……GOTO EXIT1……宏展開: ……+MOV AL,VAR1+CMP AL,VAR2+JE LOP1……+JMP EXIT1……宏調(diào)用: ……55§5.7DOS功能子程序的調(diào)用

為了了解程序運行過程中的情況,應(yīng)設(shè)法將運算結(jié)果顯示到顯示器上,最簡單的方法就是調(diào)用操作系統(tǒng)的I/O子程序,我們稱為DOS功能調(diào)用。DOS為程序設(shè)計人員提供了許多可直接調(diào)用的功能子程序。調(diào)用時需要使用軟中斷指令:INTn其中:n為中斷調(diào)用類型號,其值為00~FFH。在使用INT指令前,應(yīng)將調(diào)用的功能號送入AH,有關(guān)入口參量送入指定寄存器中。若有出口參量,中斷調(diào)用返回后,結(jié)果在指定的寄存器或存儲單元中。DOS功能子程序的調(diào)用使用軟中斷指令“INT21H”。DOS共有84個功能子程序。這些子程序的主要功能是:磁盤的讀寫控制、文件操作、目錄操作、內(nèi)存管理、基本輸入輸出管理及設(shè)置/讀出系統(tǒng)日期、時間等。§5.7DOS功能子程序的調(diào)用56下面例舉部分常用的DOS功能子程序。1.帶顯示的鍵盤輸入(1號功能)該功能子程序等待鍵盤輸入,直接按下一個鍵(即輸入一個字符),把字符的ASCII碼送入AL,并在屏幕上顯示該字符。如果按下的鍵是Ctrl-C組合鍵,則停止程序運行。如果按下TAB制表鍵,屏幕上光標(biāo)自動擴(kuò)展到緊接著的8個字符位置后面。1號功能調(diào)用,毋需入口參量,出口參量在AL中。如:MOV AH,01HINT 21H下面例舉部分常用的DOS功能子程序。572.不帶顯示的鍵盤輸入(7號功能)與1號功能類似,它僅等待鍵盤輸入一個字符,并將字符的ASCII碼送入AL中。但按下Ctrl-C組合鍵和TAB制表鍵無反應(yīng)。調(diào)用方法如下:MOV AH,7INT 21H緩沖區(qū)第一個字節(jié)存放它能保存的最大字符數(shù)(1~255,不能為‘0’!),該值由用戶程序自己事先設(shè)置。如果鍵如的字符數(shù)比此數(shù)大,那就會發(fā)出“嘟嘟”聲,而且光標(biāo)不再向右移動。2.不帶顯示的鍵盤輸入(7號功能)58緩沖區(qū)第二個字節(jié)存放用戶本次調(diào)用時實際輸入的字符數(shù)(回車鍵除外),這個數(shù)由DOS返回時自動填入。用戶從鍵盤輸入的字符從第三個字節(jié)開始存放,直到用戶輸入回車鍵為止,并將回車鍵碼(0DH)加在剛才輸入字符串的末尾上。調(diào)用時,用DS:DX寄存器指向輸入緩沖區(qū)的段基值:偏移量。例如在數(shù)據(jù)區(qū)定義的字符緩沖區(qū)如下:MAX_LEN DB 18ACT_LEN DB ?STRING DB 18 DUP(0)緩沖區(qū)第二個字節(jié)存放用戶本次調(diào)用時實際輸入的字符數(shù)(回車鍵除59

則輸入串的指令如下:MOV AX,SEG MAX_LENMOV DS,AXMOV DX,OFFSET MAX_LENMOV AH,0AHINT 21H5.字符顯示(2號功能)本功能子程序僅在屏幕上顯示單個字符。要顯示字符的ASCII碼存放在DL中。如果DL中存放退格鍵編碼,在屏幕上便向左移一個字符位置,并使該位置成為空格。移動后光標(biāo)停留在那里。如要顯示字符‘A’,可用下列幾條指令調(diào)用:MOV DL,‘A’MOV AH,2INT 21H則輸入串的指令如下:606.字符打印(5號功能)5號功能子程序把DL中的字符(ASCII碼)送入打印機接口,打印輸出。功能調(diào)用為:MOV DL,‘A’MOV AH,5INT 21H7.字符串顯示(9號功能)9號功能子程序能在屏幕上顯示多于一個的字符串。要顯示的字符串必須先放在內(nèi)存一數(shù)據(jù)區(qū)中,且字符串以美元符號‘$’作為結(jié)束標(biāo)志。非顯示字符,可以用它的ASCII碼插入字符串中間。進(jìn)行9號功能調(diào)用時,先把待顯示的字符串首地址的段基值和偏移量分別存入DS和DX中。在數(shù)據(jù)段中定義一個待顯示符號串如:STRING DB “THISISAPROGRAM”,0AH,0DH,“$”6.字符打印(5號功能)61則顯示該符號串的指令為: LEA DX,STRING MOV AH,9 INT 21H8.取中斷向量(35H號功能)35H號功能把由AL指定的中斷類型號的中斷向量從中斷向量表中取到ES:BX中。即必須把要取出的中斷類型號N送給AL,調(diào)用35H功能后,與中斷類型號N對應(yīng)的中斷向量則保存在ES:BX中。其調(diào)用示例如下:MOV AL,NMOV AH,35HINT 21H則顯示該符號串的指令為:629.設(shè)置中斷向量(25H號功能)25H號功能把由AL指定的中斷類型的中斷向量DS:DX放置在中斷向量表中。具體設(shè)置過程為:首先將要設(shè)置的中斷類型號送AL,然后把要設(shè)置的中斷服務(wù)程序的段地址和偏移量分別送DS、DX,最后再調(diào)用25H功能。典型的使用DOS功能調(diào)用存取中斷向量的程序段如下:……MOV AL,N ;取出并保存原中斷向量MOV AH,35HINT 21HPUSH BX9.設(shè)置中斷向量(25H號功能)63PUSH ESPUSH DSMOV AX,SEGINTERRUPT MOV DS,AXMOV DX,OFFSETINTERRUPTMOV AL,NMOV AH,25HINT 21HPOP DS……POP DS

PUSH ES64恢復(fù)原中斷向量POP DXMOV AL,NMOV AH,25HINT 21HMOV AH,4CH ;返回DOSINT 21HINTERRUPT: …… ;中斷服務(wù)程序IRET……恢復(fù)原中斷向量6510.讀出系統(tǒng)日期(2AH號功能)本功能子程序的執(zhí)行,將系統(tǒng)的年、月、日、星期的數(shù)據(jù)讀出,并存入指定的寄存器中:CX←年(1980~2099)DH←月(1~12)DL←日(1~31)AL←星期(0—星期日,1—星期一等)11.設(shè)置系統(tǒng)日期(2BH功能)調(diào)用本功能子程序時,必須在CX和DX中設(shè)置有效日期,其中,CX中存放年號(1980~2099),DH中存放月號(1~12),DL中存放日(1~31)。如果日期設(shè)置有效,待功能子程序返回時,(AL)=0,否則(AL)=0FFH。所以為了檢查設(shè)置是否成功,通常在調(diào)用2BH號功能后檢查AL中內(nèi)容。

10.讀出系統(tǒng)日期(2AH號功能)6612.讀出系統(tǒng)時間(2CH功能)本功能子程序從系統(tǒng)中可得到當(dāng)時的時間:時、分、秒和百分秒,它們分別存放在CX和DX寄存器中:CH←小時(0~23)CL←分(0~59)DH←秒(0~59)DL←百分秒(0~99)13.設(shè)置系統(tǒng)時間(2DH功能)調(diào)用本功能子程序時,必須在CX和DX中設(shè)置有效時間(指定有關(guān)寄存器和數(shù)據(jù)范圍與2C號功能相同)。如果設(shè)置時間有效,從功能子程序返回時,(AL)=0,否則(AL)=0FFH。

12.讀出系統(tǒng)時間(2CH功能)67§5.1匯編語言源程序的框架結(jié)構(gòu)

編制匯編語言源程序時,首先要使用段定義偽指令和段尋址偽指令來構(gòu)造一個由若干指令和數(shù)據(jù)組成的程序。構(gòu)造一個源程序的框架結(jié)構(gòu)有如下兩種格式:第一種格式:……MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND BEGIN第5章8086/8088匯編語言程序設(shè)計§5.1匯編語言源程序的框架結(jié)構(gòu)第5章8086/8068第二種格式:…… RET ;取程序段前綴首地址MAIN ENDPCODE ENDSEND BEGIN區(qū)別:兩種格式的本質(zhì)區(qū)別在于返回DOS的方法不同:對于第一種格式,采用了調(diào)用DOS系統(tǒng)的4CH功能,返回DOS。具體方法是:在要返回DOS處,安排如下兩條指令:MOV AH,4CHINT 21H對于第二格式,DOS返回方法是調(diào)用20H類型的中斷服務(wù)程序。

第二種格式:69§5.2順序結(jié)構(gòu)程序設(shè)計順序程序結(jié)構(gòu)是指完全按照順序逐條執(zhí)行的指令序列,這種結(jié)構(gòu)的流程圖除了有一個開始框和結(jié)束框外,就是若干處理框,沒有判斷框,如圖5.1所示。圖5.1順序程序的結(jié)構(gòu)形式

§5.2順序結(jié)構(gòu)程序設(shè)計70例5.1:試分別用匯編語言源程序的兩種框架結(jié)構(gòu)編制程序,求出表達(dá)式:(X×4-Y)/2的值,并保存到RESULT存儲單元中,其中X,Y均為字節(jié)變量。解:完成該功能的流程圖如圖5.2所示:圖5.2例5.1的功能實現(xiàn)流程圖例5.1:試分別用匯編語言源程序的兩種框架結(jié)構(gòu)編制程序,求出71參考程序1:DATA SEGMENT ;數(shù)據(jù)段X DB 2Y DB 4Z DB ? ;定義變量DATA ENDSSTACK SEGMENT PARA STACKDW 20H DUP(0)STACK ENDSCODE SEGMENT ;代碼段ASSUMECS:CODE,DS:DATA,SS:STACK參考程序1:72BEGIN: MOV AX,DATAMOV DS,AX ;DS賦初值MOV AL,X ;AL←XMOV CL,2SAL AL,CL ;AL←X×4SUB AL,Y ;AL←X×4-YSAR AL,1 ;AL←(X×4-Y)/2MOV Z,AL ;存結(jié)果MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND BEGINBEGIN: MOV AX,DATA73參考程序2:DATA SEGMENTX DB 2Y DB 4Z DB ?DATA ENDSSTACK SEGMENT PARA STACKDW 20H DUP(0)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKPROC1 PROC FAR ;使RET為遠(yuǎn)返回END BEGIN參考程序2:74BEGIN: PUSH DS ;入棧保存地址MOV AX,0 ;程序段前綴的首地址PUSH AXMOV AX,DATAMOV DS,AXMOV AL,X ;AL←XMOV CL,2SAL AL,CL ;AL←X×4SUB AL,Y ;AL←X×4-YSAR AL,1 ;AL←(X×4-Y)/2MOV Z,AL ;存結(jié)果RET ;取程序段前綴首地址BEGIN: PUSH DS ;入棧保存地址75PROC1 ENDPCODE ENDS§5.3分支結(jié)構(gòu)程序設(shè)計分支程序結(jié)構(gòu)可以有兩種形式,如圖5.4所示,它們分別相當(dāng)于高級語言程序中的IF-THEN-ELSE語句和CASE語句,它們適用于要根據(jù)不同條件做不同處理的情況。PROC1 ENDP§5.3分支結(jié)構(gòu)程序設(shè)計76§5.3.1用比較/測試的方法實現(xiàn)IF-THEN-ELSE結(jié)構(gòu)實現(xiàn)方法:在產(chǎn)生分支之前,通常用比較、測試的辦法在標(biāo)志寄存器中設(shè)置相應(yīng)的標(biāo)志位,然后再選用適當(dāng)?shù)臈l件轉(zhuǎn)移指令,以實現(xiàn)不同情況的分支轉(zhuǎn)移。(1)進(jìn)行比較,使用比較指令:CMP DEST,SRC該指令進(jìn)行減法操作,而不保存結(jié)果,只設(shè)置標(biāo)志位。(2)進(jìn)行測試,使用測試指令TEST DEST,SRC該指令進(jìn)行邏輯與操作,而不保存結(jié)果,只設(shè)置標(biāo)志位。§5.3.1用比較/測試的方法實現(xiàn)IF-THEN-ELS77§5.3.2用地址表法實現(xiàn)CASE結(jié)構(gòu)(即多路分支)用地址表法實現(xiàn)CASE結(jié)構(gòu)的基本思路是:將各分支程序的入口地址依次羅列形成一個地址表,讓BX指向地址表的首地址,從鍵盤接收或其他方式獲取要轉(zhuǎn)到的分支號,再讓BX與分支號進(jìn)行運算,使BX指向?qū)?yīng)分支入口地址,最后即可使用JMPWORDPTR[BX]或JMPDWORDPTR[BX]指令實現(xiàn)所要轉(zhuǎn)到的分支;程序設(shè)計流程圖如圖5.6所示:§5.3.2用地址表法實現(xiàn)CASE結(jié)構(gòu)(即多路分支)78圖5.6用地址表法實現(xiàn)多路分支的結(jié)構(gòu)框圖例5.4:編程實現(xiàn)菜單選擇,根據(jù)不同的選擇做不同的事情。

解:假設(shè)有3路分支,在地址表中的入口地址分別:A0、A1、A2;具體見圖5.7所示:

圖5.6用地址表法實現(xiàn)多路分支的結(jié)構(gòu)框圖例5.4:編程79參考程序:DATA SEGMENTMENU DB 0DH,0AH,"0:Chinese!"DB 0DH,0AH,"1:English!"DB 0DH,0AH,"2:German!"DB 0DH,0AH,"Pleasechooseonetoanswerthefollowingquestion:$"ER DB0DH,0AH,"Iamsorry,youchoosethemistake!$"參考程序:80S0 DB 0DH,0AH,"OK,PleaseanswerinChinese!$"S1 DB 0DH,0AH,"OK,PleaseanswerinEnglish!$"S2 DB 0DH,0AH,"OK,PleaseanswerinGerman!$"TAB DW A0,A1,A2 ;地址表DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXLEA DX,MENU ;顯示菜單MOV AH,9INT 21HS0 DB 0DH,0AH,"OK,Pleaseanswe81MOV AH,1 ;1號DOS功能調(diào)用,接收分支號INT 21HCMP AL,'0' ;進(jìn)行合法判斷JB ERRORCMP AL,'2'JA ERRORLEA BX,TAB ;取地址表首址SUB AL,30HSHL AL,1 ;段內(nèi)轉(zhuǎn)移乘以2,段間轉(zhuǎn)移乘以4XOR AH,AH ;AH清零ADD BX,AXJMP WORDPTR[BX] ;產(chǎn)生多分支轉(zhuǎn)移MOV AH,1 ;1號DOS功能調(diào)用,接收分支號82A0: LEA DX,S0 ;各分支程序段MOV AH,9INT 21HJMP EXIT1A1: LEA DX,S1MOV AH,9INT 21HJMP EXIT1A2: LEA DX,S2MOV AH,9INT 21HJMP EXIT1A0: LEA DX,S0 ;各分支程序段83ERROR: MOV DX,OFFSETERMOV AH,9INT 21HEXIT1: MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND START§5.3.3用轉(zhuǎn)移表法實現(xiàn)CASE結(jié)構(gòu)(即多路分支)用轉(zhuǎn)移表法實現(xiàn)CASE結(jié)構(gòu)的基本思路:將轉(zhuǎn)到各分支程序的轉(zhuǎn)移指令依次羅列形成一個轉(zhuǎn)移表,讓BX指向轉(zhuǎn)移表的首地址,從鍵盤接收或其他方式獲取要轉(zhuǎn)到的分支號,再讓BX與分支號進(jìn)行運算,使BX指向?qū)?yīng)轉(zhuǎn)移表中轉(zhuǎn)到該分支的轉(zhuǎn)移指令處,最后即可使用JMPBX指令實現(xiàn)所要轉(zhuǎn)到的分支;具體見圖5.8所示:ERROR: MOV DX,OFFSETER§5.3.384圖5.8用轉(zhuǎn)移表法實現(xiàn)多路分支的結(jié)構(gòu)框圖例5.5:編程實現(xiàn)菜單選擇,根據(jù)不同的選擇做不同的事情。解:假設(shè)有3路分支,轉(zhuǎn)移表中的轉(zhuǎn)移指令分別為:JMPSHORTA0、JMPSHORTA1、JMPSHORTA2;具體見圖5.9所示:圖5.8用轉(zhuǎn)移表法實現(xiàn)多路分支的結(jié)構(gòu)框圖85參考程序:DATA SEGMENTMENU DB 0DH,0AH,"0:Chinese!"DB 0DH,0AH,"1:English!"DB 0DH,0AH,"2:German!"DB 0DH,0AH,"Pleasechooseonetoanswerthefollowingquestion:$"參考程序:86ER DB0DH,0AH,"Iamsorry,youshoosethemistake!$"S0 DB 0DH,0AH,"OK,PleaseanswerinChinese!$"S1 DB 0DH,0AH,"OK,PleaseanswerinEnglish!$"S2 DB 0DH,0AH,"OK,PleaseanswerinGerman!$"DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXLEA DX,MENU ;顯示菜單MOV AH,9INT 21HER DB0DH,0AH,"Iamsorry,yo87MOV AH,1 ;1號DOS功能調(diào)用,接收分支號INT 21HCMP AL,'0'JB ERRORCMP AL,'2'JA ERRORLEA BX,TAB ;取地址表首址SUB AL,30HSHL AL,1 ;短轉(zhuǎn)移乘以2,近轉(zhuǎn)移乘以3,遠(yuǎn)轉(zhuǎn)移乘以5XOR AH,AH ;AH清零ADD BX,AXMOV AH,1 ;1號DOS功能調(diào)用,接收分支號88JMP BX ;產(chǎn)生多分支轉(zhuǎn)移TAB: JMP SHORT A0 ;轉(zhuǎn)移表JMP SHORT A1JMP SHORT A2A0: LEA DX,S0 ;各分支程序段MOV AH,9INT 21HJMP EXIT1A1: LEA DX,S1MOV AH,9INT 21HJMP BX ;產(chǎn)生多分支轉(zhuǎn)移89JMP EXIT1A2:LEA DX,S2MOV AH,9INT 21HJMP EXIT1ERROR: MOV DX,OFFSETERMOV AH,9INT 21HEXIT1: MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND STARTJMP EXIT190§5.4循環(huán)結(jié)構(gòu)程序設(shè)計

§5.4.1循環(huán)程序的組成1.設(shè)置循環(huán)的初始狀態(tài)如置循環(huán)次數(shù)的計數(shù)值,以及為循環(huán)體正常工作的初始狀態(tài)等;2.循環(huán)體這是循環(huán)的工作主體,它由循環(huán)的工作部分及修改部分組成。3.循環(huán)控制部分它是循環(huán)程序設(shè)計的關(guān)鍵,每一個循環(huán)程序必須選擇一個循環(huán)控制條件來控制循環(huán)的運行和結(jié)束,通常有兩種方法控制循環(huán):用計數(shù)控制循環(huán),用條件控制循環(huán)

§5.4循環(huán)結(jié)構(gòu)程序設(shè)計91§5.4.2循環(huán)程序的結(jié)構(gòu)形式循環(huán)程序有兩種結(jié)構(gòu),一種是DO-WHILE結(jié)構(gòu)形式,另一種是DO-UNTIL結(jié)構(gòu)形式。具體見圖5.10所示:DO-WHILE結(jié)構(gòu)把對循環(huán)控制條件的判斷放在循環(huán)的入口,先判斷條件,滿足條件就執(zhí)行循環(huán)體,否則退出循環(huán)。DO-UNTIL結(jié)構(gòu)是先執(zhí)行循環(huán)體然后再判斷控制條件,不滿足條件則繼續(xù)執(zhí)行循環(huán)操作,一旦滿足條件則退出循環(huán)。一般講,如果循環(huán)次數(shù)等于0的可能,則應(yīng)選擇DO-WHILE結(jié)構(gòu),否則用DO-UNTIL結(jié)構(gòu)。圖5.10循環(huán)程序的結(jié)構(gòu)形式

§5.4.2循環(huán)程序的結(jié)構(gòu)形式圖5.10循環(huán)程序的結(jié)92§5.4.3循環(huán)控制的方法

1.用計數(shù)控制循環(huán)這種方法直觀、方便,易于程序設(shè)計。只要在編制程序時,循環(huán)次數(shù)已知,就可以使用這種方法設(shè)計循環(huán)程序。然而更多的循環(huán)程序,在編制程序時并不能確切知道循環(huán)次數(shù),但是知道循環(huán)次數(shù)是前面運算或操作的結(jié)果或者被存放在某內(nèi)存單元中。例5.6:試編制程序統(tǒng)計字節(jié)變量VAR中1的個數(shù),并將它存入COUNT單元中。

解:要測試出VAR中1的個數(shù)就應(yīng)該逐位進(jìn)行測試,可根據(jù)最低位是否為1來計數(shù),然后用移位的辦法把各位數(shù)逐次移到最低位去,共需要測試8次。程序流程如圖5.11所示:§5.4.3循環(huán)控制的方法例5.6:試編制程序統(tǒng)計字節(jié)變93圖5.11例5.6的功能實現(xiàn)流程圖

圖5.11例5.6的功能實現(xiàn)流程圖94參考程序:DATA SEGMENTVAR DB37HCOUNT DB?DATA ENDSCODE SEGMENTASSUMECS:CODE,DS:DATABEGIN: MOV AX,DATAMOV DS,AXMOV AL,VAR ;AL←VAR的值MOV CX,8 ;賦循環(huán)初值XOR BL,BL ;賦計數(shù)器初值參考程序:95LL: TEST AL,1 ;測試AL的最低位JZ LL1 ;最低位為0轉(zhuǎn)LL1INC BL ;計數(shù)器加1LL1: SHR AL,1 ;邏輯右移1位LOOP LL ;循環(huán)控制MOV COUNT,BL ;COUNT←計數(shù)器BL的值MOV AH,4CH ;返回DOSINT 21HCODE ENDSEND BEGINLL: TEST AL,1 ;測試AL的最低位962.用條件控制循環(huán)

例5.8:將正整數(shù)NUM插入到一個從小到大排列好順序的正整數(shù)字節(jié)數(shù)組序列中。

分析:假設(shè)該數(shù)組的首地址和末地址分別為ARRAY_HEAD、ARRAY_END,顯然在這里需要插入的是一個數(shù),所以不一定要掃描整個數(shù)組。同時為了插入這個數(shù)據(jù),必須要空出位置,即凡是比它大的數(shù)據(jù)都應(yīng)該向地址增大的方向移動一個字節(jié),故應(yīng)該從數(shù)組的尾部向頭部查找,可逐字節(jié)取出比較。值得注意的是,應(yīng)該考慮正整數(shù)NUM大于或小于數(shù)組中的所有數(shù)的可能,即如果NUM大于數(shù)組中所有數(shù),則第一次比較就可以結(jié)束查找;如果NUM小于數(shù)組中所有數(shù),則必須及時結(jié)束查找,絕對不允許查找的范圍超出數(shù)組的首地址,當(dāng)然可以把數(shù)組的首地址或循環(huán)次數(shù)作為結(jié)束查找的條件。根據(jù)上述分析,可以得出程序流程如圖5.13所示:2.用條件控制循環(huán)例5.8:將正整數(shù)NUM插入到一97圖5.13例5.8的功能實現(xiàn)流程圖

圖5.13例5.8的功能實現(xiàn)流程圖98參考程序:NUM EQU 36HDATA SEGMENTARRAY DB 12H,24H,48H,60H,72H,84HY DB ?DATA ENDSCODE SEGMENTASSUMECS:CODE,DS:DATABEGIN: MOV AX,DATAMOV DS,AXMOV CX,Y-ARRAY ;循環(huán)次數(shù)初始化MOV AL,NUM ;插入值送AL參考程序:99LEA SI,YDEC SI;取得ARRAY的最后元素的偏移地址LOP: CMP ARRAY[SI],AL ;比較JLE INSERTMOV AH,ARRAY[SI]MOV ARRAY[SI+1],AH ;數(shù)據(jù)交換DEC SI ;修改偏移地址LOOP LOPINSERT: MOV ARRAY[SI+1],AL ;插入數(shù)據(jù)MOV AH,4CHLEA SI,Y100

INT 21HCODE ENDSEND BEGIN§5.5子程序設(shè)計

§5.5.1子程序的構(gòu)造前面我們學(xué)習(xí)了過程定義偽指令,我們也就是用它們來構(gòu)成的子程序,其格式為:子程序名 PROC (NEAR/FAR)保存信息……恢復(fù)信息RET子程序名 ENDPINT 21H§5.5子101§5.5.2子程序的調(diào)用與返回子程序的正確執(zhí)行是由子程序的正確調(diào)用和返回保證的。IBMPC機的CALL和RET指令就分別完成了子程序的調(diào)用和返回功能。1.調(diào)用指令:CALL過程名執(zhí)行CALL指令,首先保留斷點地址于堆棧中,然后轉(zhuǎn)移到目標(biāo)單元,它對PSW無影響。2.返回指令:RET一個子程序執(zhí)行的最后一條指令必定是返回指令RET,用以返回到調(diào)用子程序的斷點處。但在位置上并不一定就是是最后一條指令。它的位置靈活,并不是必須要在最后。只是習(xí)慣上我們通常將它置于子程序的最后。

§5.5.2子程序的調(diào)用與返回102§5.5.3編制子程序的要求1.子程序必須具有通用性2.注意保存信息和恢復(fù)信息要注意最先壓入堆棧的應(yīng)該最后彈出來,值得注意的是:必須搞清楚那些寄存器是必須保存的,那些又是不必要或不應(yīng)該保存的。一般來說,子程序中用到的寄存器是應(yīng)該保存的,但是如果主程序和子程序之間使用寄存器傳遞參數(shù)的話,該寄存器則不一定需要保存,特別是用來向主程序回送結(jié)果(即出口參數(shù))的寄存器,則更不應(yīng)該因保存和恢復(fù)該寄存器的內(nèi)容而破壞了應(yīng)該向主程序傳送的信息。3.選用適當(dāng)?shù)姆椒ㄔ谧映绦蚝椭鞒绦蛑g的進(jìn)行參數(shù)傳遞§5.5.3編制子程序的要求103這種主程序與子程序之間的信息傳送稱為參數(shù)傳遞,它可以有以下三種:①用寄存器傳遞參數(shù)這是最常用的一種方式,通常在參量不多的時候使用這種方法。②用地址表傳遞參數(shù)

通過地址表傳送參數(shù)的方法是在主程序中首先建立一個地址表,把要傳送給子程序的參數(shù)都存放在地址表中,然后把地址表的首地址通過寄存器傳送到子程序中去;最后子程序通過地址表取得所需參數(shù)。

③用堆棧傳遞參數(shù)這種方法是在主程序中把要傳送給子程序的參數(shù)先保存到堆棧中,然后子程序再從堆棧中取出參數(shù)以達(dá)到傳送參數(shù)的目的。

這種主程序與子程序之間的信息傳送稱為參數(shù)傳遞,它可以有以104§5.6高級匯編語言技術(shù)

§5.6.1宏匯編1.宏定義宏在使用前必須先進(jìn)行宏定義。宏定義格式為:宏指令名 MACRO 形式參數(shù),形式參數(shù),… <宏體> ENDM其中,宏指令名:宏定義的名字(即給宏體中程序段指定一個符號名),不可缺省,宏調(diào)用時要使用它,第一個符號必須是字母,其后可以是字母或數(shù)字§5.6高級匯編語言技術(shù)105MACRO…ENDM:宏定義偽指令助記符,不可缺省。它們成對出現(xiàn),表示宏定義的開始和結(jié)束,ENDM前不帶宏指令名。宏體:一段有獨立功能的程序代碼段。形式參數(shù):又稱啞元,各個啞元之間用逗號隔開,可以缺省。2.宏調(diào)用經(jīng)宏定義后的宏指令可以在源程序中調(diào)用,宏調(diào)用格式為:宏指令名 實參,實參…宏調(diào)用只需要有宏指令名,若宏定義中有形參,那么宏調(diào)用時必須帶有實際參數(shù)來替代形參,實際參數(shù)的個數(shù),順序,類型與形參一一對應(yīng),各個實參之間用逗號分開。原則上實參的個數(shù)與形參的個數(shù)相等,但匯編程序不要求它們必須相等,若實參個數(shù)大于形參個數(shù),則多余的實參不予考慮,若實參個數(shù)小于形參個數(shù),則多余的形參作“空”處理。

MACRO…ENDM:宏定義偽指令助記符,不可缺省。它們成對1063.宏展開匯編程序在對源程序匯編時,對每個宏調(diào)用作宏展開,每條插入的宏體指令前帶上加號“+”。例5.11:不帶參數(shù)的宏定義,用宏指令來實現(xiàn)回車換行。宏定義:CRLF MACROMOV DL,0DH ;回車MOV AH,2INT 21HMOV DL,0AH ;換行MOV AH,23.宏展開例5.11:不帶參數(shù)的宏定義,用宏指令來實現(xiàn)回車換107INT 21H ENDM宏調(diào)用:CRLF宏展開:將下述程序段替換宏調(diào)用語句。+MOV DL,0DH ;回車+MOV AH,2+I(xiàn)NT 21H+MOV DL,0AH ;換行+MOV AH,2+I(xiàn)NT 21HINT 21H1084.宏調(diào)用中參數(shù)傳遞宏定義中的參數(shù)可以有多個,實參可以是數(shù)字,寄存器或操作碼。宏定義還可用部分操作碼作參數(shù),但在宏定義中必須用“&”作分隔符,&是一個操作符,它在宏定義體中可作為啞元的前綴,宏展開時,可以把&前后兩個符號合并成一個符號。例5.12:宏定義帶一個參數(shù),用宏指令實現(xiàn)將AX中內(nèi)容右移任意次(小于256)。

宏定義:SHIFT MACRO N MOV CL,N SAL AX,CL ENDM宏調(diào)用1: SHIFT 44.宏調(diào)用中參數(shù)傳遞例5.12:宏定義帶一個參數(shù),用宏指令實109宏調(diào)用2: SHIFT 8宏展開1: MOV CL,4 ;AX中內(nèi)容算術(shù)左移4次 SAL AX,CL宏展開2: MOV CL,8 ;AX中內(nèi)容算術(shù)左移8次 SAL AX,CL5.宏定義嵌套在宏定義中允許使用宏調(diào)用,但必須先定義后調(diào)用。

例5.14:宏定義:AD1 MACRO M,N MOV BX,M

宏調(diào)用2: SHIFT 85.宏定義嵌套例5.14:110ADD AX,NENDMAD1M MACRO R1,R2,R3PUSH AXPUSH BXAD1 R1,R2MOV X3,AXPOP BXPOP AXENDM宏調(diào)用: AD1M CX,BX,DX宏展開: PUSH AXADD AX,N111PUSH BXAD1 R1,R2 ;此語句不占內(nèi)存MOV BX,CX ;AD1宏定義展開ADD AX,BXMOV DX,AXPOP BXPOP AX6.取消宏定義語句格式為:PURGE宏指令名,宏指令名…PURGE:偽指令助記符,不可缺省,因為經(jīng)過定義的宏指令名,不允許重新定義,必須用PURGE語句將其取消后,才能重新定義,此語句一次可以取消多個宏指令名。PUSH BX6.取消宏定義語句112

7.宏指令與子程序的區(qū)別⑴過程調(diào)用使用CALL語句,由CPU執(zhí)行,宏指令調(diào)用由宏匯編程序MASM中宏處理程序來識別。⑵過程調(diào)用時,每調(diào)用一次都要保留程序的斷點和保護(hù)現(xiàn)場,返回時要恢復(fù)現(xiàn)場和恢復(fù)斷點,增加了操作時間,執(zhí)行速度慢。而宏指令調(diào)用時,不需要這些入棧及出棧操作,執(zhí)行速度較快。⑶過程調(diào)用的子程序與主程序分開獨立存在,經(jīng)匯編后在存儲器中只占有一個子程序段的空間,主程序轉(zhuǎn)入此處運行,因此目標(biāo)代碼長度短,節(jié)省內(nèi)存空間。而宏調(diào)用是在匯編過程中展開,宏調(diào)用多少次,就插入多少次,因此目標(biāo)代碼長度大,占內(nèi)存空間多;⑷一個子程序設(shè)計,一般完成某一個功能,多次調(diào)用完成相同操作,僅入口參數(shù)可以改變,而宏指令可以帶啞元,調(diào)用時可以用實元取代,使不同的調(diào)用完成不同的操作,增加使用的靈活性。

7.宏指令與子程序的區(qū)別113§5.6.2重復(fù)匯編重復(fù)匯編偽指令語句有以下三種:1.定重復(fù)格式:REPT 表達(dá)式宏體ENDM其中,REPT…ENDM:偽指令助記符,必須成對出現(xiàn),不可省略。宏體:表示需要重復(fù)的語句序列。表達(dá)式:表示重復(fù)次數(shù)。§5.6.2重復(fù)匯編114例5.16:將2、4、8、16、32分配給連續(xù)的5個存儲單元。 NUM=1REPT5 NUM=NUM*2 DBNUM

ENDM匯編后: +DB2 +DB4 +DB8 +DB16 +DB32例5.16:將2、4、8、16、32分配給連續(xù)的5個存儲單元1152.不定重復(fù)格式:IRP 形參,<實參表> 宏體ENDM其中,IRP…ENDM:偽指令助記符,必須成對出現(xiàn),不可省略。宏體:要重復(fù)的語句序列,重復(fù)次數(shù)由參數(shù)個數(shù)決定。實數(shù)表中是每次重復(fù)時將要取的實參,實參之間用逗號隔開,實參表用尖括號<>括起來。每次重復(fù),依次取實參表中一項,代入語句序列中啞元。前面將2、4、8、16、32分配給連續(xù)的5個存儲單元的例子也可以用如下不定重復(fù)偽指令:IRP NUM,<2,4,8,16,32> DB NUM ENDM2.不定重復(fù)116例5.17:若要把AX,BX,CX,DX的內(nèi)容壓入堆棧,則可以用如下不定重復(fù)偽指令:IRP REG,<AX,BX,CX,DX> PUSH REG ENDM匯編后展開為以下四條指令: +PUSH AX +PUSH BX +PUSH CX +PUSH DX例5.17:若要把AX,BX,CX,DX的內(nèi)容壓入堆棧,則可1173.不定重復(fù)字符格式為:IRPC 形式參數(shù),字符串 宏體 ENDM其中,IRPC..ENDM:偽指令助記符,必須成對出現(xiàn),不可省略。宏體:重復(fù)執(zhí)行的語句序列,每次重復(fù)時依次用字符串中字符代替形式參數(shù),重復(fù)次數(shù)取決于字符串中字符的個數(shù)。字符串:可用尖括號也可不用尖括號括起來。例5.18:若要從堆棧中彈出4個字,分別送入DX,CX,BX,AX,則可用如下不定重復(fù)字符偽指令:IRPC REG,<DCBA> POP REG&X ENDM3.不定重復(fù)字符例5.18:若要從堆棧中118匯編后展開為以下四條指令: +POP DX +POP CX +POP BX +POP AX§5.6.3條件匯編條件匯編是對給定的條件進(jìn)行測試,匯編程序根據(jù)測試結(jié)果,將一段程序嵌入源程序匯編或不進(jìn)行匯編,它的一般格式為:IF×× 表達(dá)式 指令體1 ;條件為真匯編指令體1ELSE 指令體2 ;條件為假匯編指令體2ENDIF匯編后展開為以下四條指令:§5.6.3條件匯編119其中,IF××…ENDIF:條件匯編偽指令助記符,必須成對出現(xiàn),不可省略。IF語句后的“××”是指定的條件。如果“IF××”指定的條件為真時則宏匯編程序?qū)⒅噶铙w1中的語句匯編成相應(yīng)的目標(biāo)代碼,否則就把指令體2中的語句匯編成相應(yīng)的目標(biāo)代碼。ELSE:是任選部分,如果沒有ELSE,那么“IF××”指定的條件滿足就匯編,否則就不匯編。“IF××”條件匯編的形式見表5.1所示:其中,IF××…ENDIF:條件匯編偽指令助記符,必須成對出120例5.20:利用條件匯編偽指令,可以根據(jù)不同情況,產(chǎn)生無條件轉(zhuǎn)移指令如JMP,或產(chǎn)生條件轉(zhuǎn)移指令如JE、JNE、JB、JNB等。宏定義:GOTO MACRO LOP,X,REL,YIFB <REL>JMP LOPELSEMOV AL,XCMP AL,YJ&REL LOPENDIFENDM例5.20:利用條件匯編偽指令,可以根據(jù)不同情況,產(chǎn)生無條件121宏調(diào)用: ……GOTO LOP1,VAR1,E,VAR2……GOTO EXIT1……宏展開: ……+MOV AL,VAR1+CMP AL,VAR2+JE LOP1……+JM

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論