匯編語言第五章_第1頁
匯編語言第五章_第2頁
匯編語言第五章_第3頁
匯編語言第五章_第4頁
匯編語言第五章_第5頁
已閱讀5頁,還剩39頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、 循環(huán)程序設(shè)計 分支程序設(shè)計第5章 循環(huán)與分支程序設(shè)計順序:按順序逐條執(zhí)行指令循環(huán):分支:子程序:程序的結(jié)構(gòu)形式有循環(huán)初始狀態(tài) 控制條件循環(huán)體5.1循環(huán)程序設(shè)計:有兩種結(jié)構(gòu)形式當(dāng)條件滿足時執(zhí)行,如果有可能循環(huán)次數(shù)等于零,則選擇do while執(zhí)行循環(huán) 直到條件滿足才退出。Do while Do until 循環(huán)初始循環(huán)體 控制條件 不論哪一種結(jié)構(gòu)形式,循環(huán)程序可由以下三部分組成: 設(shè)置循環(huán)的初始狀態(tài),以及循環(huán)次數(shù)。 循環(huán)體 修改部分。 循環(huán)控制部分 用循環(huán)次數(shù)加其它條件。 循環(huán)次數(shù)未知,設(shè)定其他條件工作部分。 用循環(huán)次數(shù)作為控制條件。 5.1.2循環(huán)程序設(shè)計例 5.1編制一個程序把bx寄存器內(nèi)

2、的2進(jìn)制數(shù)用16進(jìn)制數(shù)的形式在屏幕上顯示出來。根據(jù)題目要求應(yīng)將BX中的內(nèi)容從左到右每4位一組顯示出來,共顯示4個十六進(jìn)制數(shù)位。如果顯示的數(shù)位是09,則把4位二進(jìn)制數(shù)加上30H,轉(zhuǎn)換成相應(yīng)的ASCII 30H39H;如果是AF,則應(yīng)加上37H(30H+7)轉(zhuǎn)換成ASCII碼41H46H。顯示字符可以使用DOS功能調(diào)用來實現(xiàn)(詳見第九章)是二-十六轉(zhuǎn)換程序的流程。 1、分析題意。將2進(jìn)制數(shù)轉(zhuǎn)化為16進(jìn)制數(shù),必須以4位2進(jìn)制數(shù)轉(zhuǎn)化為1位16進(jìn)制數(shù)。要轉(zhuǎn)換一個16位的2進(jìn)制數(shù),需要循環(huán)執(zhí)行4次用來轉(zhuǎn)換的程序主體再顯示時數(shù)值與ASCII碼的轉(zhuǎn)換,比如:01的ASCII碼是31 2、畫出程序框圖開始初始化

3、循環(huán)計數(shù)值把最右面的數(shù)轉(zhuǎn)換為ASCII碼顯示一個字符加上7BX循環(huán)左移一個數(shù)位是ASCII碼的AF循環(huán)計數(shù)值=0?結(jié)束例 5.1是一個典型的DO until 型循環(huán).NYYN為什么要加上7,跳過 : ; ? 這7個ASCII BX1234例:把 BX 中的二進(jìn)制數(shù)以十六進(jìn)制的形式顯示在屏幕上Prognam segment Main proc far Assume cs:prognamStart:1 Push ds2 Sub ax,ax3 Push ax MOV BX, N ; N為一個要顯示的二進(jìn)制數(shù)4 mov ch,4 ;置計數(shù)器,把BX中數(shù)分為4段,每段一個ASCII 5 Rotate:

4、mov cl,4 ;循環(huán)入口,CL為計數(shù)器,對左移4個BIT計數(shù)6 Rol bx,cl ;循環(huán)左移4次,把低4位變成4高位,最高4位變低4位7 mov al,bl ;原高4位放AL8 and al,0fh ;左4位置0,剩下右4位在AL中9 Add al,30h ;剩下右4位在AL中加30h10 Cmp al,3ah ; al-3ah0 ?11 Jl printit ; 上式中如小于等于0,則在0-9中12 Add al, 7h ;大于0則在A-F數(shù)中13 Printit: Mov dl,al ;P471 中斷21H調(diào)用,顯示AL中內(nèi)容14 Mov ah,2 ; P471 中斷21調(diào)用,顯示A

5、L中內(nèi)容15 Int 21h ; P471 中斷21調(diào)用,顯示AL中內(nèi)容16 Dec ch ;循環(huán)計數(shù)17 Jnz rotate ; 循環(huán)出口(滿足條件轉(zhuǎn)移ROTATE)18 Ret Main endpPrognam ends End start例5.2 在ADDR 單元中存放著數(shù)Y的地址,試編制一個程序把Y中1的個數(shù)存在COUNT單元中datarea segment addr dw 1010101010101010b count dw ?datarea endsprognam segment main proc far assume cs:prognam,ds:datareastart: p

6、ush dx sub ax,ax push ax moV ax,datarea mov ds,ax1 mov cx,02 Mov bx, offset addr ; 地址放BX3 mov ax,bx ; 放Y數(shù)到AX4 repeat: test ax,0ffffh ; 測試AX=0(Y=0?)5 jz exit ; 如AX=0,到EXIT句,把最后計數(shù)器CX內(nèi)容放COUNT中6 jns shift ; (最高位為0不計數(shù),為1才計數(shù))7 inc cx ; 計數(shù)8 shift: shl ax,1 ;邏輯左移1位,把低位移到高位移9 jmp repeat 10 exit: mov count,cx

7、 11 ret main endpprognam ends end start mov bx, 0newchar: mov ah, 1 ;鍵盤輸入 int 21h sub al, 30h jl exit ; 9退出 cbw xchg ax, bx mov cx, 10 mul cx;默認(rèn)被乘數(shù)為 xchg ax, bx add bx, ax ;存入 jmp newcharexit: 例:從鍵盤接收十進(jìn)制數(shù)并存入 BX( ( 010)+1 )10+2 )10+5 1 2 531 32 35 mov bx, 0newchar: mov ah, 1 ;鍵盤輸入 int 21h sub al, 30h

8、 jl exit ; 0退出 cmp al, 10 jl add_to sub al, 27h ; af cmp al, 0ah jl exit ; f退出add_to: mov cl, 4 shl bx, cl mov ah, 0 add bx, ax;存入 BX jmp newcharexit: 例:從鍵盤接收十六進(jìn)制數(shù)并存入 BX 1 a f31 61 66(016)+1) 16+0a) 16+0fx dw ?array_head dw 3,5,15,23,37,49,52,65,78,99array_end dw 105n dw 32 例5.4: (p166)將正數(shù) n 插入一個已整序

9、的正數(shù)字?jǐn)?shù)組 mov ax, n mov array_head-2, 0ffffh mov si, 0compare: cmp array_end si, ax jle insert mov bx, array_end si mov array_end si+2, bx sub si, 2 jmp short compareinsert: mov array_end si+2, ax 35152337495265789910532-1array_headarray_endn x 例5.5 :關(guān)于設(shè)定作標(biāo)志的存儲單元邏輯尺 設(shè)有數(shù)組x和Y。 x數(shù)組中有x1,x10;y數(shù)組中有y1,y10。試編制

10、程序計算z1x1十Y1 Z5x5一Y5z2x2十Y2 z6x6十Y6 z3x3一Y3 Z7x7一Y7Z4x4一Y4結(jié)果存入z數(shù)組z8x8一Y8Z9x9十Y9Z10 x10十Y10 對于這種問題,我們也可用循環(huán)程序結(jié)構(gòu)來完成。已知循環(huán)計數(shù)值為10,每次循環(huán)的操作數(shù)是可以順序取出的,但所做的操作卻有不同,這里有兩種操作:加法和減法,為了區(qū)別每次應(yīng)該做哪一種操作,可以設(shè)立標(biāo)志位,如標(biāo)志位為0做加法;為1則做減法,這樣進(jìn)入循環(huán)后只判別標(biāo)志位就可確定應(yīng)該做的操作了。顯然,這里要做10次操作就應(yīng)該設(shè)立10個標(biāo)志位,我們把它放在一個存儲單元logic_rule中,這種存儲單元一般稱為邏輯尺,本例設(shè)定的邏輯尺

11、為: 0000000011011100從低位開始所設(shè)的標(biāo)志位反映了每次要做的操作順序,最高的6位沒有意義把它們設(shè)為0。 可以畫出程序框圖如圖510所示。 編制程序如圖511所示。開始結(jié)束循環(huán)計數(shù)值=0?測試邏輯尺第I位的值初始化循環(huán)計數(shù)值I=0XI-YIXI+YIZI結(jié)果I II+1不=0=0NYData segment X dw 1,3,5,7,9,8,7,6,9,9 Y dw 1,2,3,4,3,2,1,5,6,7 Z dw 10 dup (?) Logic_rule dw 00dchData ends Code segment Main proc far Assume cs:code,d

12、s:dataStart: Push ds Sub ax,ax Push ax Mov ax,data Mov ds,ax Mov bx,0 Mov cx,10 Mov dx,logic_rule ;邏輯尺中數(shù)放DX中Next: mov ax,xbx ; 取Xi數(shù)組中的i個數(shù)后放入AX中;(BX=i, i=1,2,3,.n) Shr dx,1 ;邏輯尺中最低位移入CF中 j c subtract ;判斷CF=1/0?為1轉(zhuǎn)SUBRTACT,為0順序做下行加法 Add ax,ybx ; Xi數(shù)與Yi相加后的和放AX(BX=i, i=1,2,3,.n) Jmp short result ;第i次的和

13、要放入Zi數(shù)組中 (i=1,2,3,.n)Subtract: Sub ax,ybx ;Xi數(shù)與Yi相減后的差放AX(BX=i, i=1,2,3,.n)Result: mov zbx,ax ;把Xi數(shù)與Yi相加(減)后的和(差)放Zi數(shù)組中(BX=i, i=1,2,3,.n) Add bx,2 ;下標(biāo)加1(兩個字節(jié)) Loop next ;循環(huán)出口 RetMain endp Code ends End start這種設(shè)立邏輯尺的方法是很常用的。如,把一組數(shù)據(jù)存入存儲器時,如果其中數(shù)值為0的元素很多,也可用這種方法設(shè)立一個每位表示一個下標(biāo)的邏輯尺,(這樣的邏輯尺可能占有幾個字,由數(shù)組的長度確定。)

14、 0元素就可不占有存儲單元了。在例55中,每個標(biāo)志只占一位,如果要表示的特征數(shù)更多,則每個標(biāo)志可占有幾位,在處理方法上是完全相同的。 設(shè)立標(biāo)志位的方法,除了如邏輯尺那樣可靜態(tài)地預(yù)置外,還可以在程序中動態(tài)地修改標(biāo)志位的值以達(dá)到控制的目的,下例說明這種方法。 例56 試編制一程序:從鍵盤輸入一行字符,要求第一個鍵入的字符必須是空格符,如不是則退出程序;如是則開始接收鍵入的字符并順序存放在首地址為BUFFER的緩沖區(qū)中(空格符不存入),直到接收到第二個空格符時退出程序。 這一程序要求接收的字符從空格符開始又以空格符結(jié)束,因此程序中必須區(qū)分所接收的字符是否是第一個字符,為此設(shè)立作為標(biāo)尺的存儲單元fla

15、g,一開始將其置為0,接受第一個字符以后可將其設(shè)為1。 框圖下圖:開始結(jié)束初始化首地址置flag為0接收一個字符修改地址存入緩沖區(qū)置flag為1是第一個字符嗎?是空格符嗎?是空格符嗎?YYNNYNdata segment buffer db 80 dup (?) flag db ?data endscode segment main proc far assume cs:code,ds:datastart: push ds sub ax,ax push ax mov ax,data mov ds,ax1 lea bx,buffer ;放緩沖器地址到BX中2 mov flag ,0 ;標(biāo)志FLA

16、G置0 3 Next: mov ah,01 ;P471鍵盤輸入字符放AL,并回顯,AH=01為參數(shù)調(diào)用 int 21h ;同上5 test flag,01h ;測試FLAG位是否為106 jnz follow ;不為0后則轉(zhuǎn)FOLLOW處開始輸入字符7 cmp al,20h ;flag為0,判斷第一個字符是否為空格8 jnz exit ;輸入的字符不為空格(ASCII=20H),退出9 mov flag,1 ;輸入的字符為空格,則FLAG置110 jmp next ;轉(zhuǎn)NEXT句,轉(zhuǎn)下一個字符輸入并比較(循環(huán))11 follow: cmp al,20h ;接6行,F(xiàn)LAG為1后,輸入字符與空格

17、比較12 jz exit ;為空格轉(zhuǎn)EXIT13 mov bx,al ;不為空格,把AL內(nèi)容放地址BX中14 inc bx;地址增115 jmp next ;轉(zhuǎn)下一個字符輸入并比較(循環(huán))16 exit: retmain endp code ends end start5.1.3 多重循環(huán)程序設(shè)計 循環(huán)可以有多重結(jié)構(gòu)。多重循環(huán)程序設(shè)計的基本方法和單重循環(huán)程序設(shè)計是一致的,應(yīng)分別考慮各重循環(huán)的控制條件及其程序?qū)崿F(xiàn),相互之間不能混淆。另外應(yīng)該注意在每次通過外層循環(huán)再次進(jìn)入內(nèi)層循環(huán)時,初始條件必須重新設(shè)置。下面,我們用例子來說明。 例57 有一個首地址為A的N字?jǐn)?shù)組,請編制程序使該數(shù)組中的數(shù)按照從大

18、到小的次序整序。 我們采用起泡排序算法從第一個數(shù)開始依次對相鄰兩個數(shù)進(jìn)行比較,如次序?qū)t不做任何操作;如次序不對則使這兩個數(shù)交換位置。表51表示了這種算法的例子,可以看出,在做了第一遍的(N一1)次比較后,最小的數(shù)已經(jīng)放到了最后,所以第二遍比較只需要考慮(N1)個數(shù),即只需要比較(N一2)次,第三遍則只需要做(N一3)次比較總共最多(N-l)遍比較就可以完成排序。P187 圖58表示了起泡排序算法的程序框圖。序號 數(shù) 比較遍數(shù)1 2 3 1 8 2 5 3 16 4 84 5 32 16 84 84 3284 32 1632 8 85 5 5開始結(jié)束AIAI+1?(Count2)=0?(Cou

19、nt1)=0?(count1) n-1(count2) (count1)I 0AI AI+1I=I+1(count2) (count2)-1(count1) (count1)-1NYYYNNdata segment a dw n dup (?)data ends code segment main proc far assume cs:code,ds:datastart: push ds sub ax,ax push ax mov ax,data mov ds,ax1 mov cx,n ; 計數(shù)器值2 dec cx ;計數(shù)器值減13loop1: mov di,cx ;大循環(huán)入口(保留CX計數(shù)器

20、值,放DI)4 mov bx,0;一維數(shù)組下標(biāo)初值為05loop2: mov ax,abx ;小循環(huán)入口 一維數(shù)組下標(biāo)為BX數(shù)放AX中6 cmp ax,abx+2;下標(biāo)為BX與(BX+2)兩數(shù)比較7 jge cotinue;比較后,前者大不交換,轉(zhuǎn)COTINUE8 xchg ax,abx+2;比較后,后者大兩數(shù)交換,即大數(shù)放前面abx,小數(shù)放后面abx+2 9 mov abx,ax;同上行,大數(shù)放abx,AX為中間交換器 10cotinue: add bx,2;一維數(shù)組下標(biāo)初值為增2 11 loop loop2;小循環(huán)出口12 mov cx,di ;從保留計數(shù)器DI中恢復(fù)到CX13 loop

21、loop1;大循環(huán)出口(計數(shù)器CX減1,與11行比較)14 ret main endpcode ends end start隱含cx減1隱含cx減1 注意到一個事實,通常還沒比較到n-1遍,就已經(jīng)完成了排序。但這個算法仍然要比較n-1次才退出。這是一個弊端。 故考慮設(shè)計以下算法來解決這個問題,提高效率,我們可以來用另一種結(jié)束外循環(huán)的辦法:設(shè)立一個交換標(biāo)志位,每次進(jìn)入外循環(huán)就將交換標(biāo)志置1,在內(nèi)循環(huán)中每做一次交換操作就將該標(biāo)志位置o,在每次內(nèi)循環(huán)結(jié)束后可以測試交換標(biāo)志位,如該位為o則再一次進(jìn)入外循嚇;如該位為1,則說明上一遍比較已經(jīng)末引起交換操作,數(shù)組已整序完畢,這樣就可以立即結(jié)束外循環(huán)了。當(dāng)然

22、,這種方法在數(shù)組已整序完畢后會多做一遍比較,但在多數(shù)情況下,其比較遍數(shù)會少于(N一1),因而算法效率較高.這種算法的程序框圖如圖516所示。 Y結(jié)束開始(CX)-1=0?交換標(biāo)志=0?AI+1AI?Savecnt=0?SAVECNT=N交換標(biāo)志=1SAVECNT=SAVECNT-1CX=SAVECNTDI=數(shù)組首地址AI交換AI+1交換標(biāo)志=0NYNYYNNextra segment a dw 8,2,32,16,128,512,256,64,4extra ends data segment savecnt dw ? startaddr dw ? data endscode segment m

23、ain proc farassume cs:code,ds:data,es:extra push ds sub ax,ax push ax mov ax,extra mov es,ax mov ax,data mov ds,ax lea di,a mov startaddr,di mov cx,es:di mov savecnt,cxinit: mov bx,1 dec savecnt jz sorted mov cx,savecnt mov di, startaddrnext: add di,2 mov ax,es:di cmp es:di+2,ax jae cont xchg es:di+

24、2,ax mov es:di,ax sub bx,bxcont: loop next cmp bx,0 je initsorted: mov di, startaddr ret交換標(biāo)志交換標(biāo)志 5.2 分支程序的設(shè)計.分支程序設(shè)計就是根據(jù)不同的條件讓程序選擇不同徑中的一條. 分支程序設(shè)計分為兩種形式:相當(dāng)于 高級語言中的:判別條件 判別條件 If -then- else Case . 分支程序設(shè)計與循環(huán)程序設(shè)計比較,其特點是運行方向是向前的,在判斷條件以后只能執(zhí)行多個分支中的一個分支。分支程序設(shè)計多用條件跳轉(zhuǎn)指令 實現(xiàn)。試驗教程:例24 顯示月份名direct 試編寫一程序,要求根據(jù)用戶鍵入的

25、月份數(shù)在終端上顯示該月的英文縮寫名。本例要求根據(jù)月份數(shù)給出月份名,我們可以建立一個月份表Montab Db jan Db feb Db mar可以看出,JAN的地址為MONTAB十0,F(xiàn)EB的地址為MONTAB十3,MAR的地址為MONTAB十6,.,根據(jù)用戶給定的月份數(shù)可以計算出與其對應(yīng)的表格地址,計算法是 MoNTAB十(月份數(shù)一1)*3應(yīng)該注意,用戶鍵入的月份數(shù)是ASCII碼,必須轉(zhuǎn)換為數(shù)字才能用上述公式進(jìn)行計算。根據(jù)上述算法,可畫出程序框圖如圖211所示。在調(diào)試源程序之前:介紹一下當(dāng)ah=0a h時int 21h的動作因為該程序要求從鍵盤輸入12位數(shù),用ah=1的int21功能要輸入兩

26、次,而且還要保存。如果要求輸入的字符數(shù)更多時,該功能顯然失效??紤]用鍵盤輸入到緩沖區(qū)中斷。功能:從鍵盤輸入到緩沖區(qū),ds:dx=緩沖區(qū)首地址,(ds:dx)=緩沖區(qū)最大字符數(shù),(ds:dx+1)=緩沖區(qū)實際輸入的字符數(shù)。整個輸入過程以回車結(jié)束。1、在中斷調(diào)用的時候,先根據(jù)最大字符數(shù)(ds:dx)分配空間。等輸入完畢后把實際字符數(shù)存入(ds:dx+1)即緩沖區(qū)的第2個字節(jié)。實際字符數(shù)不包括回車。2、因為有一個回車,回車也要占用一個字節(jié)。所以在規(guī)定最大字符數(shù)的時候一定要比實際的最大字符數(shù)大1,留給回車.開始結(jié)束有輸入否?詢問MONTH?接收月份數(shù)字符轉(zhuǎn)換為數(shù)字計算相應(yīng)的表格地址顯示相應(yīng)月份YN實際

27、該程序主要的分支有兩個1、判斷輸入的數(shù)是一位的還是兩位的分別作不同的操作。2、根據(jù)地址計算的結(jié)果不同做不同的動作見源程序。 程序的分支一般用條件轉(zhuǎn)移指令來產(chǎn)生,利用轉(zhuǎn)移指令不影響條件碼的特性,可以連續(xù)的使用條件轉(zhuǎn)移指令使程序產(chǎn)生不同的分支下面我們再來看一個例子。例5.9 在附加段中,有一個按從小到大順序排列的無符號數(shù)的數(shù)組,其首地址存放在DI寄存器中,數(shù)組中的第一個單元存放著數(shù)組長度。在Ax中有一個無符號數(shù),要求在數(shù)組中查找(Ax),如找到則使CF0,并在SI中給出該元素在數(shù)組中的偏移地址;如末找到則使CF1 我們已經(jīng)遇到過多個表格查找的例子,都是使用順序查找的方法,本例是一個已經(jīng)排序的數(shù)組,

28、可以采用折半查找法以提高查找效率。折半查找法先取有序數(shù)組的中間元素與查找值進(jìn)行比較,如相等則查找成功;如查找值大于中間元素,則再取高半部的中間元素與查找值相比較;如查找值小于中間元素,則再取低半部的中間元素與查找值相比較;如此重復(fù)直到查找成功或最終末找到該數(shù)(查找不成功)為止。折半查找法的效率高于順序查找法,對于長度為N的表格,順序查找法平均要作N2次比較,而折半查找法的平均比較次數(shù)約為log2N=X 2X=10。所以,如果數(shù)組長度為100,則順序查找法平均要做50次比較,而折半查找法平均做7次比較就可以了。SEARCH退出STARTADDR (DI)(SI)=下標(biāo)(SI)取偶(DI)=(DI)+(SI)AX=DI?(SI)=2?(SI)=(SI)/2(DI)=(DI)-(S

溫馨提示

  • 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

提交評論