第08章-循環(huán)程序設計_第1頁
第08章-循環(huán)程序設計_第2頁
第08章-循環(huán)程序設計_第3頁
第08章-循環(huán)程序設計_第4頁
第08章-循環(huán)程序設計_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第8章循環(huán)程序設計8.1循環(huán)程序結構(1)置循環(huán)初值部分(這一部分僅執(zhí)行一次)有兩方面的作用:為循環(huán)工作部分置初值,包括對工作部分所涉及的某些寄存器或存儲單元置零或置其他初始值,使地址指針指向一個數(shù)據(jù)區(qū)的起始位置等;為循環(huán)控制部分置初值,包括置循環(huán)次數(shù)或置循環(huán)結束條件等。8.1循環(huán)程序結構(2)循環(huán)工作部分(需要重復執(zhí)行的程序段,是循環(huán)程序要完成的具體操作)(3)循環(huán)控制部分(隨循環(huán)工作部分一道重復執(zhí)行)作用是修改用于循環(huán)計數(shù)的寄存器的值,以及對循環(huán)結束條件是否成立作出判斷?!纠?.1】將BLKS為首址的連續(xù)N個字節(jié)數(shù)傳送至BLKD為首址的存儲區(qū),且假設這兩個存儲區(qū)不重疊,則程序流程圖如右圖所示。8.2循環(huán)指令8.2.1重復控制指令一般格式:

XXXX短標號功能:將寄存器CX默認為重復控制計數(shù)器,根據(jù)(CX)是否為0等情況來控制是轉向短標號處,還是順序執(zhí)行其后的指令(指令指定的短標號位置一般在該重復控制指令之上,轉向短標號處就實現(xiàn)了對上面程序段的重復執(zhí)行)。8.2.1重復控制指令1.LOOP指令

該指令首先使寄存器CX中的計數(shù)值減1,然后判斷(CX)是否為零。若(CX)≠0則轉至該指令指定的短標號處,即重復執(zhí)行短標號開始的程序段;否則順序執(zhí)行該LOOP指令后的指令,即不再重復執(zhí)行短標號開始的程序段。1.LOOP指令【例8.2】以下程序段的功能是,求BUFF數(shù)據(jù)區(qū)中各字節(jié)之和,并送SUM變量。

BUFFDB40H,82H,0F2H,05H,0,10H,0,18HSUMDW?

XORAX,AX

MOVSI,OFFSETBUFF

MOVCX,8

;置循環(huán)次數(shù)8AGAIN:ADDAL,[SI]ADCAH,0INCSI

;循環(huán)工作部分;LOOPAGAIN;循環(huán)控制。

MOVSUM,AX8.2.1重復控制指令2.LOOPZ指令

該指令與LOOP指令的區(qū)別僅在于,在判斷(CX)是否為零的同時還要判斷ZF標志。若(CX)≠0且ZF=1則轉至該指令指定的短標號處;否則順序執(zhí)行LOOPZ指令后的指令。8.2.1重復控制指令3.LOOPNZ指令該指令與LOOP指令的區(qū)別僅在于,若(CX)≠0且ZF=0則轉至該指令指定的短標號處;否則順序執(zhí)行LOOPNZ指令后的指令?!纠恳韵鲁绦虻墓δ苁鞘裁矗?/p>

……BUFFDB40H,82H,0F2H,05H,0,10H,0,18HSUMDW?

.

……

XORAX,AXMOVSI,OFFSETBUFFMOVCX,8AGAIN:ADDAL,[SI]ADCAH,0INCSI

CMPBYTEPTR[SI],0LOOPNZAGAIN

MOVSUM,AX程序功能:求BUFF數(shù)據(jù)區(qū)中第一個零元素之前的各字節(jié)數(shù)之和,并送SUM變量。

……BUFFDB40H,82H,0F2H,05H,0,10H,0,18HSUMDW?.

……

XORAX,AXMOVSI,OFFSETBUFFMOVCX,8AGAIN:ADDAL,[SI]ADCAH,0INCSI

CMPBYTEPTR[SI],0LOOPNZAGAIN

MOVSUM,AX8.2.2串操作指令及重復前綴1.MOVSB、MOVSW指令(串傳送指令)將DS:SI所指的源操作數(shù)傳送到ES:DI所指的目的位置(指令MOVSB實現(xiàn)字節(jié)傳送,MOVSW實現(xiàn)字傳送);然后修改SI、DI的內容使之指向下一元素位置。對SI、DI的修改取決于兩個因素:其一是操作數(shù)的屬性;其二是方向標志DF的狀態(tài)。具體修改方法:

MOVSB指令:若DF=0則SI、DI加1;否則SI、DI減1。

MOVSW指令:若DF=0則SI、DI加2;否則SI、DI減2。1.MOVSB、MOVSW指令(串傳送指令)該指令不影響狀態(tài)標志。在其前加上重復前綴REP可實現(xiàn)串從一個存儲區(qū)到另一個存儲區(qū)的傳送。在使用重復前綴的情況下,應預先將重復次數(shù)送寄存器CX,并根據(jù)需要使用指令CLD使DF置“0”,或使用指令STD使DF置“1”?!纠?.4】

以下程序的功能等同于【例8.1】中的程序功能。

DSEGSEGMENTBLKSDB(N個字節(jié)數(shù))NEQU$-BLKS……BLKDDBNDUP(?)DSEGENDSCODESEGMENTASSUMEDS:DSEG,ES:DSEG,

CS:CSEGST:MOVAX,DSEGMOVDS,AX;置源串段地址

MOVES,AX;置目的串段地址MOVCX,N;置串操作重復次數(shù)MOVSI,OFFSETBLKS;置源串偏移地址;MOVDI,OFFSETBLKD;置目串偏移地址;CLD;DF←0;設置“+”修改;REPMOVSB;重復N次字節(jié)傳送操作;MOVAH,4CHINT21H;返回DOSCSEGENDSENDST8.2.2串操作指令及重復前綴2.LODSB、LODSW指令(串裝入指令)與MOVSB、MOVSW指令的區(qū)別僅在于,這兩條指令所作數(shù)據(jù)傳送的目的位置分別為AL、AX,不涉及寄存器DI。8.2.2串操作指令及重復前綴3.STOSB、STOSW指令(串存儲指令)與MOVSB、MOVSW指令的區(qū)別僅在于,這兩條指令源操作數(shù)分別為(AL)、(AX),不涉及寄存器SI。在其前加上重復前綴REP可以使一個存儲區(qū)各單元置同一數(shù)據(jù)。【例】

以下程序的功能是什么?

DSEGSEGMENTBUFFDB100DUP(?)DSEGENDS;CSEGSEGMENTASSUMEES:DSEG,

CS:CSEGST:MOVAX,DSEGMOVES,AXMOVAH,01HINT21HMOVDI,OFFSETBUFFMOVCX,100CLDREPSTOSBMOVAH,4CHINT21HCSEG ENDS ENDSST功能:使BUFF數(shù)據(jù)區(qū)各單元存放用戶輸入的同一個字符。

DSEGSEGMENTBUFFDB100DUP(?)DSEGENDS;CSEGSEGMENTASSUMEES:DSEG,

CS:CSEGST:MOVAX,DSEGMOVES,AXMOVAH,01HINT21HMOVDI,OFFSETBUFFMOVCX,100CLDREPSTOSBMOVAH,4CHINT21HCSEG ENDS ENDSST8.2.2串操作指令及重復前綴4.CMPSB、CMPSW指令(串比較指令)將DS:SI所指的源操作數(shù)減去ES:DI所指的目的操作數(shù),即DS:[SI]-ES:[DI](注意:不是ES:[DI]-DS:[SI]),但不回送差值,只是根據(jù)減法運算產(chǎn)生狀態(tài)標志。這兩條指令對SI、DI的修改分別與MOVSB、MOVSW相同。8.2.2串操作指令及重復前綴5.SCASB、SCASW指令(串搜索指令)與CMPSB、CMPSW指令的區(qū)別僅在于,這兩條指令所規(guī)定的被減數(shù)分別為(AL)、(AX),不涉及寄存器SI。在其前加上重復前綴REPZ或REPNZ,可以在ES:DI所指的一個存儲區(qū)中尋找與(AL)、(AX)不等或相等的元素。8.2.2串操作指令及重復前綴6.REP前綴使所綴的串操作指令重復CX初值所指定的次數(shù)。在使用該前綴及其串操作指令前,應根據(jù)需要對CX設置初值。REP前綴常配合MOVSB/MOVSW,STOSB/STOSW指令使用。

8.2.2串操作指令及重復前綴7.REPZ前綴當所綴的串操作指令尚未執(zhí)行CX初值所指定的次數(shù),且所綴串操作指令的執(zhí)行使得ZF=1,則重復執(zhí)行所綴的串操作指令;否則順序執(zhí)行串操作指令的下一指令。REPZ前綴常配合CMPSB/CMPSW、SCASB/SCASW指令使用。8.2.2串操作指令及重復前綴8.REPNZ前綴與REPZ前綴的區(qū)別僅在于,使所綴的串操作指令重復執(zhí)行的條件不同。當所綴的串操作指令尚未執(zhí)行CX初值所指定的次數(shù),且所綴串操作指令的執(zhí)行使得ZF=0,則重復執(zhí)行所綴的串操作指令;否則順序執(zhí)行串操作指令的下一指令?!纠?/p>

以下程序的功能是什么?

DSEGSEGMENTBUFFDB40H,82H,0F2H,05H,0,10H,0,18HANSDB?DSEGENDS;CSEG SEGMENTASSUMEES:DSEG,CS:CSEGST:MOVAX,DSEGMOVES,AXXORAL,ALMOVDI,OFFSETBUFFMOVCX,8

CLD

REPNZSCASB MOVAL,ES:[DI] MOVANS,AL

MOVAH,4CH INT21HCSEGENDS ENDSSTART功能:將BUFF數(shù)據(jù)區(qū)中緊接第一個零元素后的字節(jié)數(shù)送ANS單元(設在末元素前存在零元素)。

DSEGSEGMENTBUFFDB40H,82H,0F2H,05H,0,10H,0,18HANSDB?DSEGENDS;CSEG SEGMENTASSUMEES:DSEG,CS:CSEGST:MOVAX,DSEGMOVES,AXXORAL,ALMOVDI,OFFSETBUFFMOVCX,8

CLD

REPNZSCASB MOVAL,ES:[DI] MOVANS,AL

MOVAH,4CH INT21HCSEGENDS ENDSSTART8.3循環(huán)程序設計

8.3.1計數(shù)控制的循環(huán)程序設計在循環(huán)程序設計中,用計數(shù)的方法實現(xiàn)循環(huán)控制是一種基本且常用的方法。這種方法適用于已知循環(huán)次數(shù)的場合。按題意確定需要重復進行的操作,將其作為循環(huán)工作部分對循環(huán)工作部分所涉及的某些寄存器、存儲單元置初始值,對計數(shù)寄存器CX置循環(huán)次數(shù);根據(jù)計數(shù)情況控制循環(huán),通常使用LOOP指令實現(xiàn)(在循環(huán)部分只是一條串操作指令時,則可通過在該串操作指令前加上REP前綴來實現(xiàn))?!纠?.7】

編寫計算N!的程序。

編程思路:(1)循環(huán)工作部分包括乘法運算??紤]到對于一個不大的N

值,N!的數(shù)值也會很大,為提高程序的適應性,故使用16位寄存器,宜使用AX作為累乘器。在使用乘法指令時,AX既提供被乘數(shù),又存放乘積。使用另一個16位寄存器提供乘數(shù)i(i=1,2,……N),考慮到LOOP指令的功能,故宜使用CX提供乘數(shù)?!纠?.7】

編寫計算N!的程序。

(2)置循環(huán)初值部分包括:累乘器的AX應置初值1。為CX置什么初值?若置初值1,則在循環(huán)工作部分應使其增1,且在循環(huán)控制部分要判斷(CX)是否等于N值。考慮到LOOP指令本身具有使CX減1,且根據(jù)(CX)是否為0來確定是否重復執(zhí)行循環(huán)工作部分的功能,故宜對CX置初值N。(3)循環(huán)控制只要使用LOOP指令即可。

計算N!的程序。

(2)置循環(huán)初值部分包括:累乘器的AX應置初值1。為CX置什么初值?若置初值1,則在循環(huán)工作部分應使其增1,且在循環(huán)控制部分要判斷(CX)是否等于N值。考慮到LOOP指令本身具有使CX減1,且根據(jù)(CX)是否為0來確定是否重復執(zhí)行循環(huán)工作部分的功能,故宜對CX置初值N。(3)循環(huán)控制只要使用LOOP指令即可。

計算N!的程序。DSEGSEGMENTNEQU(一個自然數(shù))ANSDW?DSEGENDS;CSEG SEGMENTASSUMEDS:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AX

MOVCX,NMOVAX,1;置循環(huán)初值;NT:MULCX;循環(huán)工作;LOOPNT;循環(huán)控制;MOVANS,AX;MOVAH,4CHINT21H;返回DOS。CSEGENDSENDSTART

8.3.2條件控制的循環(huán)程序設計

1.已知最大循環(huán)次數(shù)的條件控制循環(huán)程序設計(1)使用計數(shù)控制的循環(huán)程序設計方法,并在循環(huán)工作部分根據(jù)執(zhí)行情況判斷是否中途跳出循環(huán)。(2)使用LOOPZ、LOOPNZ指令實現(xiàn)循環(huán)的條件控制。

(3)使用帶有REPZ、REPNZ前綴的串比較、串搜索指令實現(xiàn)循環(huán)的條件控制?!纠?.9】

編寫一程序,用以判斷BUF1和BUF2兩個等長度的數(shù)據(jù)區(qū)中數(shù)據(jù)是否相同。相同則使FLAG單元置0,否則置-1。方法一:DSEG

SEGMENTBUF1

DB(N個字節(jié)數(shù))BUF2

DB(N個字節(jié)數(shù))COUNT

EQU

$-BUF2FLAG

DB

0DSEG

ENDS

……MOV

SI,OFFSET

BUF1-1MOV

DI,OFFSET

BUF2-1MOVCX,COUNTNT:INC

SIINC

DIMOV

AL,[SI]

CMP

AL,[DI]

JZ

L1MOV

FLAG,-1JMP

OKL1:LOOP

NTOK:MOV

AH,4CHINT

21H……方法二DSEG

SEGMENTBUF1

DB(N個字節(jié)數(shù))BUF2

DB(N個字節(jié)數(shù))COUNT

EQU

$-BUF2FLAG

DB

0DSEG

ENDS……MOV

SI,OFFSETBUF1-1MOV

DI,OFFSETBUF2-1MOVCX,COUNTNT:INCSIINCDIMOVAL,[SI]CMPAL,[DI]

LOOPZNTJZOKMOVFLAG,-1OK:MOVAH,4CHINT21H;返回DOS……方法三ASSUMEDS:DSEG,ES:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AX

MOVES,AX

MOVSI,OFFSETBUF1MOVDI,OFFSETBUF2MOVCX,COUNTCLD

REPZCMPSBJZOKMOVFLAG,-1OK:8.3.2條件控制的循環(huán)程序設計2.循環(huán)次數(shù)未知的條件控制循環(huán)程序設計【例8.12】

編寫一程序,求滿足<8000的最大的X值。DSEGSEGMENTCONSEQU8000X DW?DSEGENDSCSEGSEGMENTASSUMEDS:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AXXORAX,AXXORBX,BX;置循環(huán)初值NEXT: INCBXADDAX,BX;循環(huán)工作;

CMPAX,CONSJBNEXT;循環(huán)控制;

DECBXMOVX,BX

MOVAH,4CHINT21H;返回DOSCSEG ENDSENDST8.3.3多重循環(huán)程序設計【例8.13】編寫一程序,用以統(tǒng)計BUF數(shù)據(jù)區(qū)的64個字節(jié)中,“0”二進制位的數(shù)目。分析:(1)一個字節(jié)中“0”二進制位數(shù)目的統(tǒng)計可以用重復次數(shù)為8的循環(huán)結構解決;對64個字節(jié)的處理可以用重復次數(shù)為64的循環(huán)結構解決;前一循環(huán)結構作為本循環(huán)結構的循環(huán)工作部分,即使用二重循環(huán)就可以完成題目給定的功能。【例8.13】編寫一程序,用以統(tǒng)計BUF數(shù)據(jù)區(qū)的64個字節(jié)中,“0”二進制位的數(shù)目。(2)內層循環(huán)的構成。a.循環(huán)工作部分:判斷一個字節(jié)(如SI所指字節(jié))的某一位是否為“0”,為“0”則使計“0”寄存器(如BX)增1;否則跳過增1操作。b.置循環(huán)初值部分:計“0”寄存器置初值0,循環(huán)計數(shù)寄存器(如DH)置初值8。c.循環(huán)控制部分:對循環(huán)計數(shù)寄存器作減1計數(shù),若減1后不為0,則重復執(zhí)行循環(huán)工作部分,否則結束循環(huán)?!纠?.13】編寫一程序,用以統(tǒng)計BUF數(shù)據(jù)區(qū)的64個字節(jié)中,“0”二進制位的數(shù)目。(3)外層循環(huán)的構成a.循環(huán)工作部分:內層循環(huán),修改地址指針SI,并將內層循環(huán)產(chǎn)生的(BX),即一個字節(jié)中“0”二進制位的數(shù)目累加到某個內存單元(如COUNT單元)。b.置循環(huán)初值部分:作為存放所有字節(jié)中“0”二進制位數(shù)目的內存單元置初值0(這一工作可通過偽指令實現(xiàn));地址指針SI指向BUF數(shù)據(jù)區(qū)起始位置;外循環(huán)計數(shù)器CX置初值64。c.循環(huán)控制使用LOOP指令即可。DSEGSEGMENTBUF DB(64個字節(jié)數(shù))COUNTDW0DSEGENDSCSEGSEGMENTASSUMEDS:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AXMOVSI,OFFSETBUFMOVCX,64;置外循環(huán)初值EXL:XORBX,BXMOVDH,8MOVAL,[SI];置內循環(huán)初值

INL:RORAL,1JCNEXTINCBX;內層循環(huán)工作

NEXT:DECDHJNZINL;內循環(huán)控制

INCSIADDCOUNT,BX;外循環(huán)工作

LOOPEXL;外循環(huán)控制對該程序思考兩個問題:1)內層循環(huán)為何不使用LOOP指令作循環(huán)控制?2)在該程序中BX用做一個字節(jié)的計“0”寄存器,每當一個字節(jié)中“0”二進制位的個數(shù)統(tǒng)計完畢,則將(BX)加到COUNT單元中,這一相加工作要進行64次。如果將BX改作所有字節(jié)的計“0”寄存器,最后一次性將(BX)送COUNT單元,則程序將更為簡潔,而且程序執(zhí)行將更快。為此程序應如何修改?【例8.14】編寫一程序,以實現(xiàn)N個無序的有符號字節(jié)數(shù)組由大到小的排序

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論