匯編語言程序設(shè)計(jì)第5章.ppt_第1頁
匯編語言程序設(shè)計(jì)第5章.ppt_第2頁
匯編語言程序設(shè)計(jì)第5章.ppt_第3頁
匯編語言程序設(shè)計(jì)第5章.ppt_第4頁
匯編語言程序設(shè)計(jì)第5章.ppt_第5頁
已閱讀5頁,還剩165頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第5章 基本結(jié)構(gòu)程序設(shè)計(jì),5.1 程序設(shè)計(jì)的一般過程 5.2 順序結(jié)構(gòu)程序設(shè)計(jì) 5.3 分支程序設(shè)計(jì) 5.4 循環(huán)程序設(shè)計(jì) 5.5 字符處理,5.1 程序設(shè)計(jì)的一般過程,5.1.1 程序與程序設(shè)計(jì)的概念 要用計(jì)算機(jī)解決問題,必須事先對(duì)所要解決的問題擬定一個(gè)便于計(jì)算機(jī)工作的明確步驟,并且用計(jì)算機(jī)所能理解的“語言”把它表示出來,輸入計(jì)算機(jī),經(jīng)過調(diào)試正確,并最后運(yùn)行取得結(jié)果后才算完成了任務(wù),我們稱這一過程為程序設(shè)計(jì)。把用計(jì)算機(jī)語言表示的問題求解的一系列明確步驟,稱作解決該問題的程序,而把完成這項(xiàng)任務(wù)的活動(dòng)稱為編碼(或稱編制程序,簡稱編程);擬定一個(gè)便于計(jì)算機(jī)工作的明確步驟稱為算法設(shè)計(jì)(或稱設(shè)計(jì)問題求

2、解的方法)。程序設(shè)計(jì)與編制程序是有區(qū)別的。程序設(shè)計(jì)除了包括編碼外,還有其他過程,如算法設(shè)計(jì),程序測試等。,5.1.2 算法與流程圖 1算法 在編制程序之前,必須設(shè)計(jì)算法。算法是求解問題的方法和具體步驟,即把所要解決的問題表達(dá)為一系列計(jì)算機(jī)所能執(zhí)行的基本操作。 例如:任意給定一個(gè)正整數(shù)N,求出一切不超過N的素?cái)?shù)。 如果用篩選法來解決這一問題,則求解的步驟可概述如下:,(1) 將不超過N的整數(shù)從小到大排成一串,即 1,2,3,4,N-1,N (2) 劃去數(shù)串最左邊的數(shù)1(可使用*號(hào)標(biāo)在該數(shù)的右上角),即 1*,2,3,4,N-1,N 此時(shí)數(shù)串留下的最左邊的數(shù)為2,而2是一個(gè)素?cái)?shù),它是已識(shí)別的當(dāng)前素

3、數(shù)。,(3) 從當(dāng)前素?cái)?shù)2起,劃去數(shù)串右邊所有2的倍數(shù)的數(shù)(2本身除外),即 1*,2,3,4*,5,6*,7,8*,9,10*, 這樣劃去的都是合數(shù),而右邊剩下的就可能是素?cái)?shù)。從2起,往數(shù)串右邊看,首先遇到的是素?cái)?shù)3。 (4) 再從當(dāng)前素?cái)?shù)3起,劃去數(shù)串右邊所有3的倍數(shù)的數(shù)(3本身除外),即 1*,2,3,4*,5,6*,7,8*,9*,10*,11, 這樣劃去的都是合數(shù)。再從3起往右邊看,首先遇到的就是素?cái)?shù)5。,如此繼續(xù)下去,一直到找出的數(shù)(此數(shù)不包括在所求素?cái)?shù)中)剛好超過N為止。這時(shí),從該數(shù)起,數(shù)串左部中沒有被劃去的所有數(shù)就是所求的不超過N的全部素?cái)?shù)。 上述這樣一個(gè)工作步驟,就是求出一切

4、不超過N的素?cái)?shù)的“算法”。,2流程圖 在上述例題中,對(duì)于求解問題的算法描述用的是自然語言,包括一些數(shù)學(xué)語言。但用這種方法來描述算法,對(duì)于求解問題的流程(即邏輯結(jié)構(gòu))還不是很直觀,人們理解起來也比較慢。因此,人們往往利用具有幾何圖形直觀性的流程圖(簡稱框圖)方法來描述算法,即給出問題求解步驟的圖形表示,或是用某種類高級(jí)語言(如類PASCAL語言)來描述算法,而流程圖是描述算法最早使用的一種方法。 流程圖是框和線(或帶箭頭的線)的集合體。框用以指示做什么事,線用以指示各框之間的關(guān)系(包括順序關(guān)系)??蚓哂懈鞣N形狀,表示各種不同的用途。國際標(biāo)準(zhǔn)化組織ANSI/ISO對(duì)流程圖使用的各種圖形符號(hào)及其含義

5、作了規(guī)定,本書不再討論。,5.1.3 程序設(shè)計(jì)語言與編碼 用計(jì)算機(jī)來求解問題,還必須用計(jì)算機(jī)所能接受的語言將問題的算法表示出來,即編碼或編程序。 編程序首先碰到的是使用何種語言的問題,這取決于兩個(gè)因素,一是求解問題或任務(wù)的性質(zhì)和要求,二是所用的計(jì)算機(jī)配置了什么語言。,如前所述,在計(jì)算機(jī)系統(tǒng)的最內(nèi)層是機(jī)器語言,它是裸機(jī)能直接理解的惟一語言。用機(jī)器語言編寫程序雖可充分利用機(jī)器指令的靈活性,達(dá)到較高的效率,但這種程序是二進(jìn)制代碼形式,難讀難寫不便修改,現(xiàn)在已很少使用它,改用其外層的匯編語言來寫“要求效率較高”的程序。匯編語言的主要思想是用符號(hào)表示機(jī)器指令,即用“記憶碼”代替操作碼,用“標(biāo)識(shí)符”代替地

6、址。與機(jī)器語言相比,它易讀、易寫,可以減輕人們的勞動(dòng)。然而機(jī)器并不能直接理解匯編語言,因此必須要有一個(gè)翻譯程序?qū)R編語言程序翻譯成機(jī)器語言程序,這就是匯編程序。匯編語言是一種重要的程序設(shè)計(jì)語言。,除了匯編語言,還有許多高級(jí)程序設(shè)計(jì)語言,如PASCAL、Visual C+等。使用這類高級(jí)語言編寫的程序,同匯編語言程序一樣,也必須經(jīng)過相應(yīng)語言的“編譯程序”的翻譯,使之成為機(jī)器語言程序,才能在機(jī)器上執(zhí)行。,5.1.4 程序設(shè)計(jì)的一般過程 程序設(shè)計(jì)包含了多方面的工作,尤其是解決大型復(fù)雜問題更是如此。程序設(shè)計(jì)一般要經(jīng)歷以下幾個(gè)階段。 1.定義問題 這個(gè)階段也稱為要求定義分析,或稱需求分析,即對(duì)要解決問題

7、的意義和要求,了解明白準(zhǔn)確。這包括制定一系列清晰而無二義性的規(guī)格說明。例如,問題要求什么樣的精度,提供的輸入是什么,以及期望的結(jié)果又是什么等等。這個(gè)階段是十分重要的,對(duì)復(fù)雜問題更是這樣。因?yàn)?,需求分析產(chǎn)生的規(guī)格說明書是以后各階段的依據(jù),如果不把問題的含義弄明白、準(zhǔn)確,那將會(huì)導(dǎo)致整個(gè)設(shè)計(jì)的失敗或返工。,2構(gòu)造解法概要 這個(gè)階段也稱為功能設(shè)計(jì),主要是制定整個(gè)解法的概要,即總體設(shè)計(jì)。這包括將整個(gè)問題分解成若干任務(wù)或子任務(wù)(可按功能劃分任務(wù)),以及它們之間相互關(guān)系的描述。可采用功能模塊分割法、逐步求精法等。,3確定算法 這個(gè)階段也稱為設(shè)計(jì),主要是選擇最優(yōu)算法和數(shù)據(jù)結(jié)構(gòu)以實(shí)現(xiàn)上述的每一個(gè)任務(wù)(或子任務(wù))

8、,即根據(jù)功能模塊而選擇最適當(dāng)?shù)姆椒ê蛿?shù)據(jù)結(jié)構(gòu)以實(shí)現(xiàn)之。這是程序設(shè)計(jì)的核心步驟,也是比較困難的工作。,4編碼 這個(gè)階段也稱為程序編制或編程,主要是選擇一種程序設(shè)計(jì)語言,并用此語言具體地實(shí)現(xiàn)所設(shè)計(jì)的算法。 5調(diào)試與排錯(cuò) 通過調(diào)試來排除程序中的錯(cuò)誤,保證程序的正確。一般要作靜態(tài)檢查和動(dòng)態(tài)運(yùn)行。靜態(tài)檢查包括人工檢查和上機(jī)進(jìn)行語法檢查;動(dòng)態(tài)運(yùn)行就是根據(jù)程序在工作中所有可能的情況,例如,輸入各種不同的初始數(shù)據(jù),檢查程序執(zhí)行是否正確。,6整理文檔 程序設(shè)計(jì)的結(jié)果包括兩大部分,一是程序,二是文檔。這里講的文檔主要是包括各個(gè)設(shè)計(jì)階段的規(guī)格說明書,以及用戶使用手冊(cè)等。這是用戶使用、維護(hù)程序的依據(jù)。 7軟件測試 測

9、試是保證軟件質(zhì)量的重要手段,其主要方式是在設(shè)計(jì)測試用例的基礎(chǔ)上檢驗(yàn)軟件的各個(gè)組成部分。首先是進(jìn)行單元測試,查找各模塊在功能和結(jié)構(gòu)上存在的問題并加以糾正。其次是進(jìn)行組裝測試,將已測試過的模塊按一定順序組裝起來。最后按規(guī)定的各項(xiàng)需求,逐項(xiàng)進(jìn)行有效性測試,決定已開發(fā)的軟件是否合格,能否交付用戶使用。,8運(yùn)行/維護(hù) 已交付的軟件投入正式使用,便進(jìn)入運(yùn)行階段,這一階段可能持續(xù)若干年甚至幾十年。軟件在運(yùn)行中可能由于多方面的原因,需要對(duì)它進(jìn)行修改。其原因可能有:運(yùn)行中發(fā)現(xiàn)了軟件中的錯(cuò)誤需要修正;為了適應(yīng)變化了的軟件工作環(huán)境,需做適當(dāng)變更;為了增強(qiáng)軟件的功能需做變更等。,5.2 順序結(jié)構(gòu)程序設(shè)計(jì),例5-1 若

10、內(nèi)存的數(shù)據(jù)段中,有緩沖區(qū)BUFFER,存取數(shù)據(jù)的規(guī)則是先存儲(chǔ)一個(gè)16位帶符號(hào)的被除數(shù),再存儲(chǔ)一個(gè)16位帶符號(hào)的除數(shù),接著存儲(chǔ)商,最后存儲(chǔ)余數(shù)。 DATA SEGMENT BUFFER DW 812DH ;被除數(shù) DW 013CH ;除數(shù) DW ? ;存商 DW ? ;存余數(shù) DATA ENDS,STACK SEGMENT PARA STACK STACK DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START PROCFAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX

11、,LEA BX,BUFFER MOV AX,BX CWD ;擴(kuò)展為32位 IDIV 2BX ;帶符號(hào)數(shù)除法 MOV 4BX,AX ;存商 MOV 6BX,DX ;存余數(shù) RET START ENDP CODE ENDS END START,例5-2 編制一個(gè)實(shí)現(xiàn)兩個(gè)字(16位)相乘的程序。 MY_DATA SEGMENT M1 DW 00FFH ;被乘數(shù) M2 DW 00FFH ;乘數(shù) P1 DW ? ;存積 P2 DW ? MY_DATAENDS STACK SEGMENT PARA STACK STACK STAPN DB 100 DUP(?) STACK ENDS COSEG SEGME

12、NT,ASSUME CSCOSEG,DSMY_DATA,ESMY_DATA STR PROC FAR MULT: PUSH DS MOV AX,0 PUSH AX MOV AX,MY_DATA MOV DS,AX MOV ES,AX MOV AX,M1,MUL P2 MOV P1,AX ;存結(jié)果 MOV P2,DX RET STR ENDP COSEG ENDS END MULT,5.3 分支程序設(shè)計(jì),一般情況下,程序按順序方式執(zhí)行,有時(shí)也需要機(jī)器能根據(jù)不同情況,執(zhí)行不同的程序或程序段,這就要求所編制的程序具有判斷、選擇的能力,即需要分支結(jié)構(gòu)的程序。計(jì)算機(jī)的分析、判斷能力就是這樣實(shí)現(xiàn)的。 分支

13、結(jié)構(gòu)的基本形式如圖5-1所示,當(dāng)分支條件滿足時(shí)執(zhí)行程序段1,不滿足時(shí)執(zhí)行程序段2,當(dāng)程序段2為空時(shí),分支結(jié)構(gòu)為簡單形式。,圖5-1 分支結(jié)構(gòu)示意圖,5.3.1 轉(zhuǎn)移指令 轉(zhuǎn)移指令可以改變程序的執(zhí)行順序,它分為無條件轉(zhuǎn)移指令和條件轉(zhuǎn)移指令。 1無條件轉(zhuǎn)移指令 格式: JMP OPRD 功能:無條件轉(zhuǎn)移到OPRD所指定的位置。 說明:根據(jù)目標(biāo)地址OPRD的位置,本指令還可繼續(xù)劃分為:段內(nèi)直接短轉(zhuǎn)移、段內(nèi)直接轉(zhuǎn)移、段內(nèi)間接轉(zhuǎn)移、段間直接轉(zhuǎn)移和段間間接轉(zhuǎn)移五種具體的形式。,(1) 段內(nèi)直接短轉(zhuǎn)移。 格式: JMP SHORT LABEL 說明:LABEL為轉(zhuǎn)移后目的地址的標(biāo)號(hào),轉(zhuǎn)移后的地址標(biāo)號(hào)必須在-

14、128+127之間。 (2) 段內(nèi)直接轉(zhuǎn)移。 格式: JMP NEAR LABEL 說明:LABEL為轉(zhuǎn)移后目的地址的標(biāo)號(hào),轉(zhuǎn)移后的地址標(biāo)號(hào)必須在-32 768 +32 767之間。此外,一般將段內(nèi)直接短轉(zhuǎn)移和段內(nèi)直接轉(zhuǎn)移合并起來,寫為JMP LABEL的形式,具體屬于哪種轉(zhuǎn)移由CPU在執(zhí)行期間自動(dòng)判斷。,(3) 段內(nèi)間接轉(zhuǎn)移。 格式: JMP reg/mem 說明:轉(zhuǎn)移的偏移量在寄存器/存儲(chǔ)器中。 (4) 段間直接轉(zhuǎn)移。 格式: JMP FAR PTR LABEL 說明:LABEL為轉(zhuǎn)移后目的地址的標(biāo)號(hào),轉(zhuǎn)移后的地址與指令所在的地址不在同一個(gè)代碼段中,因此CS和IP均需改變。,(5) 段間間

15、接轉(zhuǎn)移。 格式: JMP DWORD PTR mem 說明:轉(zhuǎn)移后目的地址在存儲(chǔ)器中,因?yàn)镃S和IP均需改變,所以需要32位存儲(chǔ)器操作數(shù)。,例5-3 JMP END ;轉(zhuǎn)移到標(biāo)號(hào)END處,CS不變,IP改變 JMP FAR PTR NEXT ;轉(zhuǎn)移到標(biāo)號(hào)NEXT處,CS改變,IP改變 JMP DWORD PTR SI ;將DSSI開始的32位數(shù)據(jù)作為轉(zhuǎn)移地址, ;CS改變,IP改變,2條件轉(zhuǎn)移指令 80 x86的條件轉(zhuǎn)移指令比較多,它以某些標(biāo)志位的邏輯運(yùn)算作為依據(jù),若滿足指令所規(guī)定的條件,則程序執(zhí)行轉(zhuǎn)移,否則順序執(zhí)行。在這類指令中,轉(zhuǎn)向的目的地址必須在轉(zhuǎn)移指令的-128列或+127個(gè)字節(jié)之間,

16、這些指令對(duì)標(biāo)志位無影響,指令的助記符也不惟一。 格式: JCC LABEL 功能: 如果滿足判斷條件CC則轉(zhuǎn)移到標(biāo)號(hào)LABEL處,否則繼續(xù)執(zhí)行下一條指令。,說明:本指令還可繼續(xù)劃分成以下四種情況: (1) 檢測某一標(biāo)志位的條件轉(zhuǎn)移指令如表5-1所示。,表5-1 檢測某一標(biāo)志位的條件轉(zhuǎn)移指令,(2) 根據(jù)兩個(gè)無符號(hào)數(shù)比較結(jié)果來決定轉(zhuǎn)移的條件轉(zhuǎn)移指令如表5-2所示。,表5-2 根據(jù)兩個(gè)無符號(hào)數(shù)比較結(jié)果來決定轉(zhuǎn)移的條件轉(zhuǎn)移指令,(3) 根據(jù)兩個(gè)帶符號(hào)數(shù)比較結(jié)果來決定轉(zhuǎn)移的條件轉(zhuǎn)移指令如表5-3所示。,表5-3 根據(jù)兩個(gè)帶符號(hào)數(shù)比較結(jié)果來決定轉(zhuǎn)移的條件轉(zhuǎn)移指令,(4) CX/ECX為0時(shí)轉(zhuǎn)移的條件轉(zhuǎn)移

17、指令如表5-4所示。,表5-4 CX/ECX為0時(shí)轉(zhuǎn)移的條件轉(zhuǎn)移指令,例5-4 設(shè)(AL)=(DL),執(zhí)行指令 CMP AL,DL JZ NEXT 的結(jié)果是:指令JZ NEXT執(zhí)行完后將跳轉(zhuǎn)到NEXT標(biāo)號(hào)處繼續(xù)執(zhí)行。 例5-5 設(shè)CL內(nèi)容為一無符號(hào)數(shù),執(zhí)行指令 CMP CL,10 JB NEXT 的結(jié)果是:如果(CL) 10,則跳轉(zhuǎn)到NEXT標(biāo)號(hào)處繼續(xù)執(zhí)行;如果(CL)10,則繼續(xù)執(zhí)行下一條指令。,例5-6 設(shè)CL內(nèi)容為一帶符號(hào)數(shù),執(zhí)行指令 CMP CL,0 JNG NEXT 的結(jié)果是:如果CL為負(fù)數(shù)或0,則跳轉(zhuǎn)到NEXT標(biāo)號(hào)處繼續(xù)執(zhí)行;如果CL為正數(shù),則繼續(xù)執(zhí)行下一條指令。,5.3.2 分支

18、程序設(shè)計(jì) 在分支程序中,對(duì)條件的判斷結(jié)果只有兩種:“是”或者“不是”。因此,分支程序一般有兩種結(jié)構(gòu):不完全的雙分支結(jié)構(gòu)和完全的雙分支結(jié)構(gòu),如圖5-2所示。圖5-2(a)是不完全的雙分支結(jié)構(gòu),圖5-2(b)是完全的雙分支結(jié)構(gòu)。在不完全的雙分支結(jié)構(gòu)中,一個(gè)分支需要完成一定的任務(wù),而另一個(gè)分支不需要完成任何任務(wù);在完全的雙分支結(jié)構(gòu)中,兩個(gè)分支都分別有各自的任務(wù)。,圖5-2 分支程序的一般結(jié)構(gòu) (a) 不完全的雙分支結(jié)構(gòu);(b) 完全的雙分支結(jié)構(gòu),例5-7 給定兩個(gè)數(shù)X和Y,分別在X、Y是無符號(hào)數(shù)和帶符號(hào)數(shù)的情況下比較X、Y的大小。若X大,則輸出字母X,若Y大,則輸出字母Y。 NAME EX_COMP

19、ARE_XY STACK STACKSEG 500 MYDATA SEGMENT RW X DW 0F040H ;指定X、Y的值 Y DW 7321H MYDATA ENDS MYCODE SEGMENT ER ASSUME DSMYDATA,SSSTACK,CSMYCODE,START:PUSH DS MOV AX,0 PUSH AX MOV AX,MYDATA MOV DS,AX MOV AX,X CMP AX,Y ;無符號(hào)數(shù)情況下的比較 JA XN_BIG MOV DL,Y ;Y大,輸出Y MOV AH,02H INT 21H,XN_BIG:MOV DL,X ;X大,輸出X MOV AH

20、,02H INT 21H MOV AX,X CMP AX,Y ;帶符號(hào)數(shù)情況下的比較 JG XS_BIG MOV DL,Y ;Y大,輸出Y MOV AH,02H INT 21H,XS_BIG:MOV DL,X ;X大,輸出X MOV AH,02H INT 21H MOV AH,4CH INT 21H MYCODE ENDS END START,1利用比較轉(zhuǎn)移指令實(shí)現(xiàn)分支 用于比較、判斷的指令有:比較指令CMP、串比較指令CMPS、串搜索指令SCAS。用于實(shí)現(xiàn)轉(zhuǎn)移的指令有:無條件轉(zhuǎn)移指令JMP和各種類型的條件轉(zhuǎn)移指令。它們都可以互相配合以實(shí)現(xiàn)不同情況的分支。對(duì)于多路分支的情況,可以采用多次判斷轉(zhuǎn)

21、移的方法實(shí)現(xiàn)。每次判斷轉(zhuǎn)移形成兩路分支,n次判斷轉(zhuǎn)移可以形成n+1路分支。,例5-8 數(shù)據(jù)塊的傳送。 把內(nèi)存中某一區(qū)域的源數(shù)據(jù)塊傳遞到另一區(qū)域。若源數(shù)據(jù)塊與目的數(shù)據(jù)塊之間地址沒有重疊,可直接用數(shù)據(jù)傳送指令或串操作中的傳送指令實(shí)現(xiàn)。若它們之間的地址重疊,如何實(shí)現(xiàn)數(shù)據(jù)塊的傳送呢?試編制一程序來解決這種情況的數(shù)據(jù)塊傳送問題。 問題分析:先判斷源地址加數(shù)據(jù)塊長度是否小于目的地址,若小于,可按增量的方式傳送;若不小于,則要把指針改為指向數(shù)據(jù)塊的底部,然后采用減量方式傳送。(這里假設(shè)從低地址區(qū)域向高地址區(qū)域傳送。)程序描述如下:,DATA SEGMENT STRG DB 1000 DUP(?) STG1

22、EQU STRG+7 STG2 EQU STRG+25 STRSE EQU 50 DATA ENDS STACK SEGMENT PARA STACK STACK STAPN DB 100 DUP(?) STACK ENDS COSEG SEGMENT ASSUME CSCOSEG,DSDATA, ESDATA,SSSTACK,GOO PROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV ES,AX MOV CX,STRSE ;計(jì)數(shù)器值送CX MOV SI,OFFSET STG1 MOV DI,OFFSET STG2 CLD ;

23、增量方式(DF標(biāo)志清零),PUSH SI ;將偏移量STG1入棧 ADD SI,STRSE-1 ;源地址加上塊長 CMP SI,DI ;比較源串地址與目的串地址的大小 POP SI ;將偏移量STG1出棧 JL OK ;若SIDI轉(zhuǎn)移,表明無重疊區(qū),按增量方式傳送 STD ;減量方式傳送,表明有重疊區(qū) ADD SI,STRSE-1 ;指向數(shù)據(jù)塊底部 ADD DI,STRSE-1 OK: REP MOVSB ;重復(fù)傳送50個(gè)數(shù)據(jù) RET GOO ENDP COSEG ENDS END GOO,本程序設(shè)計(jì)時(shí),考慮了兩種情況:一是無重疊數(shù)據(jù)源,即源數(shù)據(jù)塊長度小于目的地址,按增量方式傳送;二是有重疊數(shù)

24、據(jù)源,即源數(shù)據(jù)塊長度大于目的地址,按減量方式傳送。任何一個(gè)串操作指令,可在其前面加上一個(gè)重復(fù)操作前綴REP,于是指令就重復(fù)執(zhí)行直至在寄存器CX中的操作次數(shù)滿足要求為止。重復(fù)操作是否完成的檢測是在操作以前進(jìn)行的:若初始化操作次數(shù)為0,它不會(huì)引起重復(fù)操作;若基本操作是一個(gè)影響ZF標(biāo)志的操作,在重復(fù)操作前綴字節(jié)中也可以規(guī)定與標(biāo)志ZF相比較的值。在基本操作執(zhí)行以后,ZF標(biāo)志與指令的值不等,則重復(fù)終結(jié)。,在重復(fù)的基本操作執(zhí)行期間,操作數(shù)指針(SI與DI)和操作數(shù)寄存器在每一次重復(fù)后修改,然而指針將保留重復(fù)前綴字節(jié)的偏移地址。若一個(gè)無重復(fù)操作指令,被外部中斷源中斷,則在中斷返回以后,可以恢復(fù)重復(fù)操作指令。

25、應(yīng)避免串操作指令的重復(fù)前綴與別的兩種前綴同時(shí)使用。CLD指令是DF標(biāo)志清零指令,即使DF=0,將串操作指令設(shè)置為自動(dòng)增量指令。,2利用表實(shí)現(xiàn)分支 在處理實(shí)際問題時(shí),對(duì)于分支比較少的情況用IF_THEN_ELSE結(jié)構(gòu)是最簡便可行的,但對(duì)于分支很多的情況,再使用IF_THEN_ELSE結(jié)構(gòu)實(shí)現(xiàn)程序就會(huì)變得十分冗長。例如,編制一個(gè)具有建立文件、修改文件、刪除文件、顯示文件和退出應(yīng)用程序返回操作系統(tǒng)功能的管理文件的菜單程序,最好不要用IF_THEN_ELSE結(jié)構(gòu)。在這種情況下,比較好的方法是使用CASE結(jié)構(gòu)來實(shí)現(xiàn)分支。在匯編語言中,通常是使用跳轉(zhuǎn)表法實(shí)現(xiàn)CASE結(jié)構(gòu)。,具體實(shí)現(xiàn)時(shí),需要兩個(gè)步驟:一是構(gòu)

26、造成跳轉(zhuǎn)表,二是使用跳轉(zhuǎn)地址、轉(zhuǎn)移指令或關(guān)鍵字實(shí)現(xiàn)分支。跳轉(zhuǎn)表存儲(chǔ)時(shí)可采用連續(xù)存儲(chǔ)的方法,可將跳轉(zhuǎn)表存儲(chǔ)在內(nèi)存的一片連續(xù)單元中,表中的內(nèi)容可以是跳轉(zhuǎn)地址、轉(zhuǎn)移指令或關(guān)鍵字等。根據(jù)跳轉(zhuǎn)表中存儲(chǔ)的內(nèi)容,將利用表實(shí)現(xiàn)分支,即根據(jù)表內(nèi)地址分支,根據(jù)表內(nèi)轉(zhuǎn)移指令分支或根據(jù)表內(nèi)關(guān)鍵字分支這樣三種方法,如圖5-3所示。,圖5-3 利用表實(shí)現(xiàn)分支及其分類,1) 根據(jù)表內(nèi)地址分支 例5-9 某工廠有8種產(chǎn)品的加工程序R0到R7分別存放在以SBR0,SBR1,SBR7為首地址的內(nèi)存中。而這8個(gè)首地址偏移量連續(xù)存放在以BASE為首址的跳轉(zhuǎn)表內(nèi)。設(shè)這8種產(chǎn)品的編號(hào)分別為0,1,7。若現(xiàn)在已知目前要加工的產(chǎn)品編號(hào),應(yīng)如

27、何編制一段程序,利用“跳轉(zhuǎn)表”的方法自動(dòng)轉(zhuǎn)入該種產(chǎn)品的加工程序? 分兩個(gè)方面來討論: (1) 如何構(gòu)成跳轉(zhuǎn)表? (2) 如何根據(jù)已知的編號(hào)從表中查出該種產(chǎn)品加工程序的入口地址,而首要的問題就是要先求出該種產(chǎn)品對(duì)應(yīng)的表項(xiàng)地址。,圖5-4 跳轉(zhuǎn)表, 跳轉(zhuǎn)表的組成如圖5-4所示。表開始的第一個(gè)單元的地址稱作表基地址(或表首地址)。要查找的元素在表中的地址叫表項(xiàng)地址。 如:加工程序R1的入口偏移地址SBR1在表中的地址(表項(xiàng)地址)是BASE+2。不同的加工程序?qū)?yīng)有不同的表項(xiàng)地址。 表項(xiàng)地址相對(duì)于基地址的偏差字節(jié)數(shù)稱作偏移量。如表項(xiàng)地址BASE+2相對(duì)于表基地址的偏移量是2。, 表的使用。根據(jù)上述分析

28、,可看出: 表項(xiàng)地址 = 表基地址 + 偏移量 在這里表基地址是已知的。通過分析表的結(jié)構(gòu),可看出偏移量由產(chǎn)品編號(hào)乘2求得,因而表項(xiàng)地址就可求出了。由此得到編寫程序的算法思想,畫出流程圖如圖5-5所示。,圖5-5 表分支流程圖,程序描述如下: DATA SEGMENT BASE DW SBR0,SBR1,SBR2,SBR3 DW SBR4,SBR5,SBR6,SBR7 BN DB ? ;產(chǎn)品編號(hào) DATA ENDS STACK SEGMENT PARA STACK STACK DB 100 DUP(?) STACK ENDS COSEG SEGMENT ASSUMECSCOSEG,DSDATA,

29、SSSTACK,START PROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV AL,BN MOV AH,0 ADD AL,AL ;求偏移量 =產(chǎn)品編號(hào)2 MOV BX,OFFSET BASE ;將表首址送入BX中 ADD BX,AX ;求表項(xiàng)地址,MOV AX,BX ;將加工程序的入口地址送入AX中 JMP AX RET START ENDP COSEG ENDS END START,圖5-6 命令鍵跳轉(zhuǎn)表,設(shè)12個(gè)命令鍵的編號(hào)分別為011。跳轉(zhuǎn)表中每3個(gè)單元存放著一條轉(zhuǎn)移指令。分別對(duì)應(yīng)著各命令鍵的分支轉(zhuǎn)移指令。如果已獲取了

30、所按下的命令鍵的編號(hào)X,并已將其送入寄存器AL,那么實(shí)現(xiàn)轉(zhuǎn)向相應(yīng)的命令子程序去執(zhí)行的程序段可描述如下:,MOV AH,0 MOV BL,AL ADD AL,AL ADD AL,BL ;編號(hào)乘3為偏移量 MOV BX,OFFSET BASE0 ;取表首址 ADD BX,AX ;求表地址 JMP BX,從上述程序可以看出,仍然要根據(jù)已知量(編號(hào))求表地址。由于每一指令在表中占了3個(gè)單元,所以用編號(hào)乘3得偏移量。跳轉(zhuǎn)表中存放的是轉(zhuǎn)移指令,所以在求出表地址后,直接轉(zhuǎn)去執(zhí)行表地址內(nèi)的指令就可以實(shí)現(xiàn)分支了。,3) 根據(jù)關(guān)鍵字分支 這類問題形式可以多種多樣,關(guān)鍵字可以是給定的,也可以是在表中的或是表中給出了

31、關(guān)鍵字的地址等等,然后根據(jù)關(guān)鍵字的內(nèi)容分支。 例5-11 有一臺(tái)主機(jī)為8臺(tái)外部設(shè)備服務(wù),對(duì)于每臺(tái)外設(shè)的服務(wù)程序已經(jīng)編好并已分別存放在以首址為SR0,SR1,SR7的主機(jī)的內(nèi)存中,每臺(tái)外設(shè)有一條聯(lián)絡(luò)線與主機(jī)中的寄存器相連,如圖5-7所示。,圖5-7 系統(tǒng)框圖,當(dāng)所有的外設(shè)沒有提出服務(wù)請(qǐng)求時(shí),所有聯(lián)絡(luò)線上均為“0”信號(hào)。當(dāng)其中一臺(tái)(且同一時(shí)刻只許一臺(tái))外設(shè)要求為之服務(wù)時(shí),就在其聯(lián)絡(luò)線上發(fā)出“1”信號(hào)。通過查詢主機(jī)寄存器中的關(guān)鍵字,就可以得知是哪臺(tái)外設(shè)發(fā)出的服務(wù)請(qǐng)求。關(guān)鍵字與外設(shè)的對(duì)應(yīng)關(guān)系如下:,編程實(shí)現(xiàn)時(shí),仍是先造一張表,表內(nèi)存放關(guān)鍵字值與其對(duì)應(yīng)的外設(shè)服務(wù)程序入口地址。如圖5-8所示,表的首地址為

32、BASE。,圖5-8 關(guān)鍵字表,DATA ENDS STACK SEGMENT PARA STACK STACK DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CSCODE,DSDATA,SSSTACK START PROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX,5.4 循環(huán)程序設(shè)計(jì),5.4.1 重復(fù)控制指令 該類指令在循環(huán)的首部或尾部確定是否進(jìn)行循環(huán)。重復(fù)控制指令的目的地址必須在本指令的-128+127字節(jié)范圍之內(nèi),這些指令對(duì)標(biāo)志位無影響,對(duì)于串操作及數(shù)據(jù)塊操作是很有用的。在80 x8

33、6中,所有循環(huán)程序結(jié)構(gòu)的循環(huán)次數(shù)計(jì)數(shù)器均使用CX/ECX。重復(fù)控制指令如表5-5所示。,表5-5 重復(fù)控制指令,例5-12 在4.4.4節(jié)中講述指令操作數(shù)基址變址尋址時(shí),曾舉了下述一個(gè)例子: XOR EAX,EAX ;EAX0 MOV EBX,OFFSET ARRAYSTR ;EBX數(shù)組ARRAYSTR的基地址 MOV ECX,LENGTH ARRAYSTR MOV ESI,0 ;變址寄存器ESI指向0 ALAB: ADD EAX,EBX+ESI ;利用基址加變址得到數(shù)組元素 ADD ESI,4 ;增加變址 LOOP ALAB ;繼續(xù),該程序中就用到了循環(huán)指令LOOP。為得到數(shù)組元素,可將數(shù)組

34、ARRAYSTR的基地址送到基址寄存器EBX中,而變址寄存器ESI初始化時(shí)先清0。每循環(huán)一次,只要修改變址寄存器ESI的內(nèi)容,即將ESI增4,就可得到參與加運(yùn)算的數(shù)組元素了。,例5-13 在字節(jié)數(shù)組中找出第一個(gè)非0數(shù)據(jù)。 DATA SEGMENT ARRAY DB 0,0,0,0,0,33,54,18,0,78,26,55 COUNT EQU $-ARRAY DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,START:MOV AX,DATA MOV DS,AX MOV CX,COUNT ;數(shù)據(jù)個(gè)數(shù) MOV DI,-1 AGAIN:INC DI CMP

35、 ARRAYDI,0 ;與0比較 LOOPZ AGAIN ;相等就循環(huán) MOV DX,DI ;非0數(shù)據(jù)的地址 MOV AH,4CH INT 21H CODE ENDS END START,說明:本程序的構(gòu)成未采用過程形式描述,返回命令使用的是: MOV AH,4CH INT 21H,例5-14 在字符串中查找給定的字符,找到顯示Y,否則顯示N。設(shè)給定的字符在數(shù)據(jù)段中給出,例如,需查找字符A。 DATA SEGMENT STRING DB KKDKTRGPASDFJJFJ STR EQU $-STRING DATA ENDS CODE SEGMENT ASSUMECS:CODE,DS:DATA

36、START:MOV AX,DATA MOV DS,AX,MOV CX,STR MOV SI,-1 MOV AL,A ;查找數(shù)據(jù)送AL NEXT:INC SI CMP AL,STRINGSI ;比較 LOOPNE NEXT ;不相等就循環(huán) JNZ NOTFOU ;未找到,退出 MOV DL,Y ;找到了輸出字符Y MOV AH,2 INT 21H JMP QUIT,NOTFOU: MOV DL,N ;未找到輸出字符N MOV AH,2 INT 21H QUIT: MOV AH,4CH INT 21H CODE ENDS END START,5.4.2 循環(huán)程序的基本結(jié)構(gòu) 1循環(huán)程序的組成部分 循

37、環(huán)程序一般由四個(gè)部分組成: (1) 初始化部分:為循環(huán)做準(zhǔn)備工作,包括建立指針,置計(jì)數(shù)器,設(shè)置其他變量的初始值等; (2) 循環(huán)體:完成循環(huán)的基本操作,是循環(huán)程序的核心部分; (3) 修改部分:修改操作數(shù)地址等,為下次循環(huán)做準(zhǔn)備; (4) 控制部分:修改計(jì)數(shù)器,查看循環(huán)控制條件,進(jìn)行循環(huán)控制。,2循環(huán)程序的基本結(jié)構(gòu)形式 循環(huán)程序的基本結(jié)構(gòu)形式分為“先執(zhí)行,后判斷”結(jié)構(gòu)和“先判斷,后執(zhí)行”結(jié)構(gòu)。 1) “先執(zhí)行,后判斷”結(jié)構(gòu) 在這種結(jié)構(gòu)中,進(jìn)入循環(huán)后,先執(zhí)行一次循環(huán)體后,再判斷循環(huán)是否結(jié)束。對(duì)“先執(zhí)行,后判斷”結(jié)構(gòu)而言,至少要執(zhí)行一次循環(huán)體,如圖5-9所示。,圖5-9 “先執(zhí)行,后判斷”結(jié)構(gòu)圖,

38、例5-15 試編制一個(gè)程序統(tǒng)計(jì)一個(gè)數(shù)據(jù)塊中負(fù)元素的個(gè)數(shù)。 問題分析:一字節(jié)帶符號(hào)數(shù)中,最高位(即符號(hào)位)為1的數(shù)為負(fù)數(shù)。要統(tǒng)計(jì)負(fù)數(shù)個(gè)數(shù)即查看每一個(gè)數(shù)的符號(hào)位,并統(tǒng)計(jì)符號(hào)位為1 的個(gè)數(shù)。這是有規(guī)律地重復(fù),因此,可用循環(huán)程序?qū)崿F(xiàn)。,DATA SEGMENT D1 DB -1,-3,5,6,9, ;定義若干字節(jié)帶符號(hào)數(shù) RS DW ? ;存放負(fù)元素 DATA ENDS CODE SEGMENT ASSUME CSCODE,DSDATA START PROC FAR PUSH DS MOV AX,0 PUSH AX,MOV AX,DATA MOV DS,AX MOV BX,OFFSET D1 ;建數(shù)據(jù)

39、指針 MOV CX,10 ;置計(jì)數(shù)器初值 MOV DX,0 ;置結(jié)果初值,統(tǒng)計(jì)負(fù)數(shù)的個(gè)數(shù)值存放在DX中 LOP1:MOV AX,BX CMP AX,0 ;用AND AX,AX也可以 JGE JUS INC DX,JUS: INC BX DEC CX ;循環(huán)次數(shù)減1 JNE LOP1 MOV RS,DX RET START ENDP CODE ENDS END START,2) “先判斷,后執(zhí)行”結(jié)構(gòu) 這種結(jié)構(gòu),進(jìn)入循環(huán)后,首先判斷循環(huán)結(jié)束的條件,再視判斷結(jié)果決定是否執(zhí)行循環(huán)體。“先判斷,后執(zhí)行”結(jié)構(gòu)中,如果一進(jìn)入循環(huán)就滿足循環(huán)結(jié)束條件,循環(huán)體將一次也不執(zhí)行,即循環(huán)次數(shù)為零,所以又稱為“可零迭代

40、循環(huán)”,如圖5-10所示。,圖5-10 “先判斷,后執(zhí)行”結(jié)構(gòu)圖,例5-16 AX寄存器中有一個(gè)16位二進(jìn)制數(shù),編程序統(tǒng)計(jì)其中值為1的位的個(gè)數(shù)。統(tǒng)計(jì)結(jié)果存放在CX寄存器中。 問題分析:這個(gè)程序最好用“先判斷,后執(zhí)行”的結(jié)構(gòu),AX寄存器中的數(shù)為全0,則不必再作統(tǒng)計(jì)工作了。 從圖5-10看出,一進(jìn)入循環(huán),首先是控制部分,先進(jìn)行判斷,再看這個(gè)程序的循環(huán)和控制部分之間有沒有明顯的分界。程序段描述如下:,5.4.3 多重循環(huán) 有些問題比較復(fù)雜,一重循環(huán)不夠用,必須使用多重循環(huán),這些循環(huán)是一個(gè)套一個(gè)的。雙重循環(huán)程序的一般結(jié)構(gòu)如圖5-11所示。從圖5-11中可以看出,內(nèi)循環(huán)必須完整地包含在外循環(huán)中,循環(huán)可以

41、嵌套、并列,但不可以交叉,絕對(duì)不允許從外循環(huán)中直接跳到內(nèi)層循環(huán)中。 注意:千萬不要使循環(huán)返回到初始化部分,否則會(huì)出現(xiàn)死循環(huán)。,圖5-11 雙重循環(huán)程序框圖,例5-17 編制計(jì)算矩陣向量相乘的程序。比如:,計(jì)算公式為,展開為,使用雙重循環(huán)在于:計(jì)算每一個(gè)ci時(shí),均有4項(xiàng),這是一重循環(huán),而ci共有4個(gè),這又是一重循環(huán)。所以要完成該題,就需要使用雙重循環(huán)來計(jì)算。這就是說,每一個(gè)ci的計(jì)算過程都是相同的。因此可先考慮編制出一個(gè)計(jì)算ci(先固定i=1)的程序,為便于循環(huán),把矩陣A的元素按行依次相鄰存放,即a11,a12,a13,a14,a21,a22,a23,a24,a31,把向量B和C的元素也依次相鄰

42、存放,在數(shù)據(jù)段里定義數(shù)據(jù)項(xiàng)如下:,A DB a11,a12,a13,a14 DB a21,a22,a23,a24 DB a31,a32,a33,a34 DB a41,a42,a43,a44 B DB b1,b2,b3,b4 C DW 4 DUP(?),數(shù)據(jù)的存儲(chǔ)分配如下: A0:a11 A4:a21 A8:a31 A12:a41 A1:a12 A5:a22 A9:a32 A13:a42 A2:a13 A6:a23 A10:a33 A14:a43 A3:a14 A7:a24 A11:a34 A15:a44 B0:b1 C0:c1 B1:b2 C2:c2 B2:b3 C3:c3 B3:b4 C4:

43、c4,其中,小寫字母a11,a12,a44,b1,b4等均代表具體的無符號(hào)數(shù)。,接下來應(yīng)考慮c2的計(jì)算。計(jì)算c2和計(jì)算c1有兩點(diǎn)不同:一是數(shù)據(jù)A從a21開始,而不是a11,也就是從A4開始,即SI從4開始而不是從0開始;二是結(jié)果存放在C2中,而不是C0中。其中,第一點(diǎn)不同,由于在計(jì)算c1的過程中SI每次加1,到計(jì)算完c1時(shí),SI的值恰好是4,這一要求自然滿足;第二點(diǎn)不同,可以利用基址寄存器BX,開始給BX送初值0,每循環(huán)一次加2,利用CBX間接尋址方式訪問ci的方法解決。c3、c4的計(jì)算也是一樣的。,c2的計(jì)算過程可看成是新的循環(huán)的初始部分,只是循環(huán)控制部分如果都用LOOP指令,都是用CX作為

44、計(jì)數(shù)器的。因此需要將控制計(jì)算4個(gè)ci的CX的計(jì)數(shù)值暫時(shí)保存起來。比如,存放在其他此程序不用的寄存器里、一個(gè)字存儲(chǔ)變量里或堆棧中。這里先將它暫時(shí)壓入堆棧,在使用它之前(執(zhí)行LOOP指令前)再從堆棧里彈出送回CX。,這里出現(xiàn)了一個(gè)循環(huán)程序的工作部分又是一個(gè)循環(huán)程序的情況,這就是一重循環(huán)套一重循環(huán),稱為雙重循環(huán)。計(jì)算一個(gè)ci的循環(huán)叫做內(nèi)循環(huán);計(jì)算所有ci的循環(huán)叫做外循環(huán)。對(duì)于多重循環(huán),一定要分清層次,內(nèi)、外循環(huán)的四個(gè)組成部分應(yīng)如何劃分,一點(diǎn)也不能模糊。外循環(huán)的準(zhǔn)備部分包括0SI、0BX和4CX,其中,0 SI也是內(nèi)循環(huán)的準(zhǔn)備部分;內(nèi)循環(huán)的準(zhǔn)備部分同時(shí)也是外循環(huán)的工作部分,包括PUSH CX、0DI、

45、0CBX和4CX,當(dāng)外循環(huán)重復(fù)沒有達(dá)到4次時(shí),這些操作被外循環(huán)重復(fù)執(zhí)行。如果不加分析地把控制轉(zhuǎn)移出循環(huán),那將是錯(cuò)誤的。,給出一組可以進(jìn)行計(jì)算的具體數(shù)據(jù),定義在數(shù)據(jù)段以A為起始單元的區(qū)域中,計(jì)算結(jié)果存放在數(shù)組C里。為了程序簡便、明了,本例沒有寫出二進(jìn)制轉(zhuǎn)化為十進(jìn)制輸出計(jì)算結(jié)果的指令序列。程序描述如下:,NAME EX DATA SEGMENT A DB 1,0,2,3 DB 0,1,1,0 DB 3,0,1,0 DB 4,2,0,1 B DB 0,1,1,0 C DW 4 DUP(?) TOP DB ?,DATA ENDS STACK SEGMENT PARA STACK STACK STAPN

46、 DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX MOV SI,0 MOV BX,0 MOV CX,4,LOOP1: PUSH CX MOV DI,0 MOV WORD PTR CBX,0 MOV CX,4 LOOP2: MOV AH,0 MOV AL,ASI MUL BDI ;BDI*AL ADD CBX,AX ;CBXCBX+AX,INC SI INC D

47、I LOOP LOOP2 ADD BX,2 ;確定存放下一個(gè)ci值的地址 POP CX LOOP LOOP1 MOV AH,4CH INT 21H CODE ENDS END START,注意:當(dāng)內(nèi)、外重循環(huán)均要求使用CX計(jì)數(shù)器時(shí),可先將外循環(huán)計(jì)數(shù)器CX的內(nèi)容壓棧,待內(nèi)循環(huán)處理完后,再將外循環(huán)計(jì)數(shù)器CX的內(nèi)容彈出棧,用此方法來解決內(nèi)、外重循環(huán)均要求使用CX計(jì)數(shù)器而帶來的沖突。,例5-18 使用冒泡排序法將內(nèi)存中給定的10個(gè)帶符號(hào)數(shù)按照從小到大的順序重新排列出來。 分析:算法編制的基本思想是采用兩兩比較的方法:先拿an與an-1比,若anan-1,則不交換,反之則交換;然后用an-1與an-2相

48、比,按同樣原則決定是否交換,這樣一直比下去,最后用a2與a1相比,也按同樣原則決定是否交換,當(dāng)?shù)谝淮未笱h(huán)結(jié)束時(shí),數(shù)組中的最小值冒到了前面。但是數(shù)組尚未按大小排列好,還要進(jìn)行第二次大循環(huán),這樣,數(shù)組中的第二個(gè)最小值,也上升到頂部這樣不斷地循環(huán)下去,若數(shù)組的長度為n,則最多經(jīng)過n-1次上述的大循環(huán),就可以使數(shù)組按大小的次序排列整齊。在每一個(gè)大循環(huán)中,數(shù)兩兩比較的次數(shù),在第一次大循環(huán)時(shí)為n-1;在第二次大循環(huán)時(shí)為n-2;,依據(jù)上述基本思想就可以寫出程序了。但在實(shí)際中,有的數(shù)組不需要經(jīng)過n-1次大循環(huán)就已經(jīng)排列整齊了。也就是說,按上述基本思想寫出的程序,有時(shí)存在不必要的循環(huán),這樣就使得程序的效率不高

49、。為了在程序中消除不必要的循環(huán),可設(shè)置一個(gè)標(biāo)志,在每次大循環(huán)開始時(shí),置此標(biāo)志為0;若在整個(gè)大循環(huán)中,兩兩比較后,發(fā)生過交換,則置此標(biāo)志為-1。然后在下一次大循環(huán)開始時(shí),檢查此標(biāo)志,若不為0,表示數(shù)組未排列好,繼續(xù)進(jìn)行循環(huán);若為0,則表示數(shù)組已按大小次序排列好(每次兩兩比較時(shí),都是大的數(shù)在后,小的數(shù)在前,故不用交換),就停止循環(huán)。下面給出的程序就是按這一思想編制的。,SORT_DA SEGMENT ARRAY DW 1273,5346,0FF7FH,1080H,0FFFFH,55ABH DW 3069H,5C00H,56DEH,0B69H COUNT EQU $-ARRAY SORT_DA EN

50、DS STACK SEGMENT PARA STACK STACK DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CSCODE,DSSORT_DA ASSUME ESSORT_DA,SSSTACK,STR PROC FAR START:PUSH DS MOV AX,0 PUSH AX MOV AX,SORT_DA MOV DS,AX MOV ES,AX MOV BL,0FFH A1: CMP BL,0 JE A4 XOR BL,BL MOV CX,COUNT SHR CX,1 DEC CX XOR SI,SI,A2: MOV AX,ARRAYSI C

51、MP AX,ARRAYSI+2 JLE A3 XCHG ARRAYSI+2,AX MOV ARRAYSI,AX MOV BL,0FFH A3: INC SI INC SI LOOP A2 JMP A1 A4: RET STR ENDP CODE ENDS END START,需要指出的是,排序是一種非常有用的操作,第9章介紹的折半查找,其前提就是要求表格中的數(shù)據(jù)(或字符)的排列是有次序的。例如,對(duì)于數(shù)字,要求它按數(shù)字的大小排列,字符則按其ASCII碼值的大小排列。于是對(duì)一個(gè)無次序的表來講,要對(duì)其進(jìn)行折半查找首先要使用某種排序方法,如使用冒泡法對(duì)其進(jìn)行排序。,2按條件控制循環(huán) 有些情況下,計(jì)數(shù)次

52、數(shù)無法事先確定,但循環(huán)次數(shù)與問題中的某些條件有關(guān),這些條件可以檢測到,這時(shí)采用條件控制循環(huán)為好。 使用條件:循環(huán)次數(shù)與某些條件有關(guān),條件可以檢測。 使用形式:檢測、比較、判斷。 例5-16中,統(tǒng)計(jì)寄存器AX中值為“1”的個(gè)數(shù)就屬于這種類型的問題。,因?yàn)槭孪炔⒉恢兰拇嫫鞯那闆r,若是全零,已不必再循環(huán);若僅最高位為1,則移位一次即可;若最低位為1,則要移位16次,即循環(huán)16次。循環(huán)結(jié)束的條件就看寄存器中是否為全0,當(dāng)然對(duì)于這個(gè)問題來說,也可以采用計(jì)數(shù)方法。無論什么情況,都強(qiáng)迫循環(huán)進(jìn)行16次,不過當(dāng)AX為零時(shí),循環(huán)16次統(tǒng)計(jì)結(jié)果,“1”的個(gè)數(shù)仍為0。這樣的問題采用計(jì)數(shù)方法控制就顯得太不合適了。,例

53、5-19 求一個(gè)數(shù)的平方根。 用減奇數(shù)次數(shù)的方法,求出一個(gè)數(shù)的近似平方根,這個(gè)平方根是一個(gè)整數(shù)。如求17的平方根,可以用17相繼減去奇數(shù)1,3,5,7,當(dāng)結(jié)果為負(fù)時(shí)停止,即 17-1-3-5-7-90 可以看出,17在減了5次奇數(shù)后結(jié)果變負(fù)。可近似認(rèn)為17的平方根為4或5。在下面的程序中,結(jié)果將為4。,DATA SEGMENT NUM DW 1CE4H ANS DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV DX,0H ;存放結(jié)果的寄存器清0 MOV CX,01H ;置第1個(gè)奇

54、數(shù),AGAIN: SUB NUM,CX ;減去奇數(shù) JL TOEND ;奇數(shù)已比持續(xù)相減的結(jié)果大,退出 INC DX ;減一次奇數(shù),結(jié)果增1 ADD CX,02H ;生成下一個(gè)奇數(shù) JMP AGAIN TOEND:MOV ANS,DX ;平方根送ANS中 MOV AH,4CH INT 21H CODE ENDS END START,3用邏輯尺控制循環(huán) 用戶輸入的一串代碼,稱為邏輯尺,作為分支的依據(jù)。 例5-20 某程序所需的12個(gè)參數(shù)值存于BUFFER起始的緩沖區(qū)中,對(duì)BUFFER中的第1、2、5、7、10個(gè)參數(shù)值需調(diào)用函數(shù)Y2*X進(jìn)行計(jì)算,對(duì)BUFFER中的第3、4、6、8、9、11、12個(gè)

55、參數(shù)值需調(diào)用函數(shù)Y4*X進(jìn)行計(jì)算。現(xiàn)要求使用一邏輯尺編程實(shí)現(xiàn)對(duì)BUFFER中的參數(shù)處理。,問題分析:由于分支的條件不規(guī)則,可建立一個(gè)與要求相對(duì)應(yīng)的邏輯尺(位串)0011010110110000來作為控制循環(huán)的條件。程序如下: DATA SEGMENT BUFFER DW 101,202,33,44,55,66,77,808,909,123,678,987;X的值 BLOCK DW 12 DUP(?) ;Y的保留單元 LOGRUL EQU 0011010110110000B ;前12位為邏輯尺,順序?yàn)?、2、12 DATA ENDS CODE SEGMENT ASSUME CSCODE,DSDA

56、TA,STARTPROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV DX,LOGRUL ;邏輯尺DX MOV CX,12 LEA BX,BUFFER ;BX指向X LEA SI,BLOCK ;SI指向Y,AGAIN:MOV AX,BX ;取X RCL DX,1 ;邏輯尺左移一位CF JC ANOTH ;CF=1,轉(zhuǎn)ANOTH CALL FUN1 ;CF=0,調(diào)用FUN1 NEXT: MOV SI,AX ;保存Y INC BX INC BX ;指向下一個(gè)X INC SI INC SI ;指向下一個(gè)Y LOOP AGAIN RET,START ENDP CODE ENDS END START ANOTH:CALL FUN2 ;調(diào)用FUN2 JMP NEXT FUN1 PROC ;Y2X ADD AX,AX RET FUN1 ENDP FUN2 PROC ;Y4X ADD AX,AX ADD AX,AX RET FUN2 ENDP,關(guān)于邏輯尺的討論: (1) 邏輯尺既不是參與運(yùn)算的常數(shù),又不是指令,而是判斷分支的依據(jù),猶如尺子可以描述布的長短一樣。 (2)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論