循環(huán)和分支程序設(shè)計(jì)(書)_第1頁(yè)
循環(huán)和分支程序設(shè)計(jì)(書)_第2頁(yè)
循環(huán)和分支程序設(shè)計(jì)(書)_第3頁(yè)
循環(huán)和分支程序設(shè)計(jì)(書)_第4頁(yè)
循環(huán)和分支程序設(shè)計(jì)(書)_第5頁(yè)
已閱讀5頁(yè),還剩99頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第5章

程序設(shè)計(jì)方法概述順序程序設(shè)計(jì)分支程序設(shè)計(jì)循環(huán)程序設(shè)計(jì)子程序設(shè)計(jì)5.6模塊化開(kāi)

始5.1

概述匯編語(yǔ)言程序設(shè)計(jì)的一般步驟流程圖返回本章首頁(yè)5.1.1匯編語(yǔ)言程序設(shè)計(jì)的一般步驟返回本節(jié)匯編語(yǔ)言程序設(shè)計(jì)一般有以下幾個(gè)步驟:分析題意,確定算法;分析和理解題意,找出合理的算法及適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu);根據(jù)算法畫出程序流程圖;根據(jù)流程圖編制程序;上機(jī)調(diào)試程序;任何程序必須經(jīng)過(guò)調(diào)試才能檢查出你的設(shè)計(jì)思想是否正確,以及你的程序是否符合你的設(shè)計(jì)思想。調(diào)試時(shí)可用工具——DEBUG進(jìn)行調(diào)試。程序結(jié)構(gòu)有:順序、循環(huán)、分支、和子程序四種數(shù)據(jù)結(jié)構(gòu)。運(yùn)行程序;5.1.2流程圖流程圖的概念流程圖是由特定的幾何圖形、指向線、文字說(shuō)明來(lái)表示數(shù)據(jù)處理的步驟,形象描述邏輯控制結(jié)構(gòu)以及數(shù)據(jù)流程的示意圖。流程圖具有簡(jiǎn)潔、明了、直觀的特點(diǎn)。流程圖符號(hào)表示起止框:表示程序的開(kāi)始和結(jié)束。起止框(2)判斷框處理框調(diào)用框(5)指向線(6)連接框返回本節(jié)5.2

順序程序設(shè)計(jì)下面舉例說(shuō)明順序程序的設(shè)計(jì)。例5.1數(shù)組中存放若干個(gè)字節(jié)元素。將兩個(gè)數(shù)組對(duì)應(yīng)元素相加,運(yùn)算結(jié)果存放在第三個(gè)數(shù)組相應(yīng)結(jié)果單元中。本例每個(gè)數(shù)組有1個(gè)元素,每個(gè)元素占

1字節(jié)長(zhǎng)。(1)

E:\MASM>EDITC100.ASMDATA

SEGMENTDATA1

DB1;被加數(shù)DATA2

DB5;加數(shù)DATA3

DB0;和初值DATACODEENDSSEGMENTASSUME

CS:CODE,

DS:DATASTART:

MOV

AX,

DATA;清進(jìn)位標(biāo)志AL,DATA1[SI]MOV

DS,

AXMOV

SI,

0CLCMOVADCAL,DATA2[SI]

;字節(jié)相加MOV

DATA3[SI],

AL;輸出顯示部MOV

BX,OFFSET

DATA3MOV

DL,

[BX]ADD

DL,

30HMOV

AH,

2INT

21H;返回DOSAX,

4C00H21HMOVINTCODE

ENDS(2)

E:\MASM>MASMC100.ASMC100E:\MASM>LINKE:\MASM>C100<ENTER>6(5)E:\MASM>DEBUG

C100.EXE5.2

順序程序設(shè)計(jì)【例5.2】試編寫一程序計(jì)算以下表達(dá)式的值。w=(v-(x*y+z-540))/x式中x、y、z、v均為有符號(hào)字?jǐn)?shù)據(jù)。設(shè)x、y、z、v的值存放在字變量X、Y、Z、V中,結(jié)果存放在雙字變量W之中,程序的流程圖如圖5.1返所回本示章。首頁(yè)序運(yùn)算程序源程序如下:DATAW

DWDATASTACKSEGMENTDW

200DW

100DW

3000V

DW

100002

DUP(?)ENDSSEGMENT

STACKDB

200DUP(0)ENDSSTACKCODE

SEGMENTASSUME

DS:DATA,CS:CODE,SS:STACKSTART:MOVMOVMOVDS,AXAX,XAX,DATA;DATA→AXIMULY;(X)*(Y)→DX:AXMOVCX,AXMOVBX,DX;(DX:AX)→(BX:CX)MOVAX,ZCWD;(Z)符號(hào)擴(kuò)展ADDCX,AX→(BX:CX)ADCBX,DX;(BX:CX)+(DX:AX)SUBCX,540SBBBX,0;(BX:CX)-540→(BX:CX)CWD;(V)符號(hào)擴(kuò)展SUB

AX,CXSBB

DX,BX;(DX:AX)-(BX:CX)→(DX:AX)IDIV

X;(DX:AX)/XMOV

W,AXMOV

W+2,DX;商→W;余數(shù)DX→W+2MOV

AH,4CHINT

21HCODE

ENDS ;退出DOS狀態(tài)5.3

分支程序設(shè)計(jì)用條件轉(zhuǎn)移指令實(shí)現(xiàn)程序分支用跳轉(zhuǎn)表實(shí)現(xiàn)多路分支返回本章首頁(yè)1、分支程序的結(jié)構(gòu)形式:分支程序結(jié)構(gòu)可以有兩種形式:一個(gè)是二路分支:IF—THEN—ELSE形式;一個(gè)是多路分支:CASE形式;5.3.1用條件轉(zhuǎn)移指令實(shí)現(xiàn)程序分支JZ結(jié)果為常零用的語(yǔ)JN句Z

:結(jié)果不為零JS/結(jié)果為負(fù)JNS結(jié)果為正JL小于JLE小于等于JG大于JGE大于等于在某一種確定條件下,只能執(zhí)行多個(gè)分之中一個(gè)分支。例5.3

已知X=80,

X值在數(shù)據(jù)段中定義,編寫程序:若X>50則

Z

=X+Y,否則Z

=X-Y

,結(jié)果存入Z。X,Y,Z均為字?jǐn)?shù)據(jù)。SEGMENT;數(shù)據(jù)段中DW

80ENDSDATAX

DATACODESEGMENTASSUME

DS:DATA,SS:STACK,CS:CODESTART:MOVAX,DATAMOVDS,AXMOVAX

,

XCMPAX,

50JGHIGHSUBAX

,

YJMPEXITHIGH:ADDAX,

YEXIT:MOVZ,AXCODEMOV

AH,4CHINT

21HENDSENDSTART【例5.4】編寫計(jì)算下面函數(shù)值的程序:1Y=

0-1X>0X=0X<0設(shè)輸入數(shù)據(jù)為X、輸出數(shù)據(jù)Y,且皆為字節(jié)變量。程序流程圖如圖5.2所示。流程圖如下:圖5.2

分支運(yùn)算程序流程圖【例5.4】編寫計(jì)算函數(shù)值的程序:程序如下:SEGMENTDB -10DATAXY DB

?DATA

ENDSSTACK SEGMENT

STACKDB 200

DUP(0)ENDSSTACKCODE

SEGMENTASSUME

DS:DATA,SS:STACK,CS:CODESTART:

MOV

AX,DATAMOV

DS,AXMOV

AL,

XCMP

AX,0JGE

A1MOV

Y,-1;與0進(jìn)行比較;X≥0轉(zhuǎn)A1;X<0時(shí),-1→YJMPEXIT;X>0轉(zhuǎn);X=0時(shí),0→YA1:JGA2A2MOVY,0JMPEXITA2:

MOV;X>0,1→YEXIT:

MOVINTY,1AH,4CH21HCODE

ENDSENDSTART【例5.5】求最值【例5.5】試編一程序,求三個(gè)帶符號(hào)字?jǐn)?shù)據(jù)中的最大值,并將最大值存入MAX字單元中。設(shè)三個(gè)帶符號(hào)數(shù)分別在三個(gè)字變量X、Y、Z中存儲(chǔ)。程序流程圖如圖5.5所示例5.5程序流程圖MOV

AX,XCMP

AX,YL1Y;Y>Z?;X>Y?JGMOV

AX,CMPAX,ZJGEXITL2:

MOVAX,ZJMPEXITAX,ZL1:CMP;X>Z?JLEL2程序如下:STACKSEGMENT

STACKDB

200

DUP(0)STACKDATAENDSSEGMENTXDW30YDW20ZDW10MAXDW

?DATAENDSCODE

SEGMENTASSUME

DS:DATA,SS:STACK,CS:CODESTART:

MOVMOVMOVCMPAX,DATADS,AXAX,XAX,Y;X>Y?JGMOVL1AX,Y;Y>Z?L2:CMPJGMOVJMPAX,ZEXITAX,ZEXITL1:

CMP

AX,

Z;X>Z?JLE

L2EXIT:

MOV

MAX,AXMOV

AH,4CHCODEINT

21HENDSENDSTART返回本節(jié)2、多路分支程序設(shè)計(jì)方法.程序分支一般用條件轉(zhuǎn)移命令來(lái)產(chǎn)生,連續(xù)用條件轉(zhuǎn)移命令使程序產(chǎn)生多個(gè)分支。例5.6在DI寄存器中,數(shù)組中的第一個(gè)單元存放著數(shù)組長(zhǎng)度,在AX中有一個(gè)無(wú)符號(hào)數(shù),要求在數(shù)組中查找(AX),如找到則使CF=0,并在SI中給出該元素在數(shù)組中的偏移地址;如未找到則使

CF=1.方法:順序折半法.折半查找法先取有序數(shù)組的中間元素與查找值比較,如相等則查找成功;如查找值大于中間元素,則再取高半部的中間元素與查找值相比較;如查找值小于中間元素,則再取低半部的中間元素與查找值比較;如此重復(fù),直到查找成功或最終未找到該數(shù)為止。例5.6在附加段中,有一個(gè)按從小到大順序排列的無(wú)符號(hào)數(shù)組,其首地址存放在DI寄存器中,數(shù)組中的第一個(gè)單元存放著數(shù)組長(zhǎng)度,在AX中有一個(gè)無(wú)符號(hào)數(shù),

要求在數(shù)組中查找(AX),如找到,則使CF=0,并在SI中給出該元素在數(shù)組中的偏移地址,如未找到,則使CF=1在一個(gè)長(zhǎng)度為N的有序數(shù)據(jù)組R中,查找元素K的折半查找算法:n

;⑴初始化被查找數(shù)組的首尾下標(biāo),low

1,hig⑵若low>high,則查找失敗,置CF=1,退出程序。否則,計(jì)算中點(diǎn):mid

(low+high)/2;⑶K與中點(diǎn)元素r[mid]比較,若k=r[mid],則找成功,退出程序;若k<r[mid],則轉(zhuǎn)步驟(4);high

mid-1,轉(zhuǎn)若k>r[mid],則轉(zhuǎn)步驟(5

);low

mid+1,轉(zhuǎn)⑷低半部查找(lower),high

mid-1,返回步流程圖如下:Dseg;低地址元素的下標(biāo).segmentLow_

idx dw

?High_

idx dw

?;高地址元素的下標(biāo).Dseg

ends.B_search

procnear;查找元素“55”(ax)Mov

ax

,

55Cmpax

,es:[di+2]

;(ax) 第一個(gè)元素,比較.Ja

chk_last ;(ax)>第一個(gè)元素,則Lea si

,es:[di+2]

;(ax)≤第一個(gè)元素,則第到chk_last一個(gè)元素

S;(ax)=第一個(gè)元素,則退出.;(ax)≠第一個(gè)元素,則CF=1,未找Je

exitStcJmp

exit;退出.Chk_last:Mov

si

,es:[di]Shl si

,1;

元素個(gè)數(shù)

S.;長(zhǎng)度*2=到最后元素(下標(biāo))的字節(jié)數(shù)Add

si

,diCmp

ax

,es:[si];形成最后元素的地址;比較,<最后元素,則轉(zhuǎn)searchSearch

:(low_idx)Movlow_idx

,1;最低元素下標(biāo)=1Movbx

,es:[di];元素個(gè)數(shù)

(bx)Movhigh_idx

bx;最高元素下標(biāo)(high_idx=元素個(gè)數(shù))Movbx

,di;保存數(shù)組的起始地址(bx)mid:movcx

,low_idxmovdx

,high_idx;low

>high_idxcmpcx

,dx;若low>high,則轉(zhuǎn)no_match,置cja

no_match:

int[(low+high)/2]

cx(中間)addcx

,dx;shrcx

,1;中間元素下標(biāo)(si)movsi

,cx;shlsi

,1;將下標(biāo)值*2形成元素compare:;數(shù)組基地址BX+元素偏偏移地址移量 元素地ax<中間元素:dec

cxmov high_idx

,cxjmp

mid;若(ax)<(mid),則;1、中間元素下標(biāo)值:(cx)

(cx)-;

2、且(cx)

high_idx;3、轉(zhuǎn)mid,將中間元素變?yōu)楦叩刂穐igher:inc

cxmov low_idx

,cx變?yōu)榈偷刂吩豭mp

mid.;若(ax)>(mid);1、中間元素下標(biāo)值:(cx)

(cx)+;2、low_idx (cx)將中間元素;3、轉(zhuǎn)mid,計(jì)算中間元素;未找到,置cf=1;彈出dsNo_match:StcExit:Pop

dsRetB_searchendp程序首先把查找值與數(shù)組的第一個(gè)元素和最后

一個(gè)元素相比較,如果找到或該數(shù)小于第一個(gè)元素或大于最后一個(gè)元素,則結(jié)束查找,否則從SEARCH開(kāi)始折半查找。SEARCH①?gòu)腟EARCH開(kāi)始,首先把數(shù)組長(zhǎng)度作為數(shù)組中間元素下標(biāo),把它從數(shù)組的第一個(gè)單元中取出來(lái),并使它成為偶數(shù),然后再把下標(biāo)加到DI中以形成數(shù)組的中間元素的地址并開(kāi)始比較查找;②如果比較相等則轉(zhuǎn)至ALL_DONE結(jié)束查找;③否則要確定下一步的查找是在數(shù)組的低半部還是高半部中進(jìn)行。它們要做的工作是:①首先檢查下標(biāo)是否等于2,如果等于2則說(shuō)明整個(gè)查找失敗,應(yīng)把CF置1并轉(zhuǎn)至ALL_DONE結(jié)束查找;②其次,把下標(biāo)除以2,以便做進(jìn)一步的折半查找,然后使下標(biāo)形成偶數(shù)值;③如果要在低半部查找,則從當(dāng)前的地址(DI)中減去下標(biāo)值(si)以形成新的查找地址;④如果要在高半部查找,則把下標(biāo)值加到當(dāng)前地址值中。以上過(guò)程重復(fù)進(jìn)行直到下標(biāo)值減到2或者查Dsegsegment定義數(shù)據(jù)段地址Starteddw?存放數(shù)組的首DsegendsCsegsegment代碼段Bsearch

procAssumePushPushMovMovPopfarcs:

cseg

,

ds:

dsegdsaxax

,dsegds

,axax ;將已存入ax中的數(shù)彈出個(gè)元素嗎?JaCmp ax

,es:[di+2] ;(ax)≤第一chklast ;到CHKLAST取偏移地址lea址存入siexitjestcjmpchklast:si

,es:[di+2] ;到≤時(shí),則取地;=退出,CF=0不置位;<置CF=1,未找到轉(zhuǎn)EXITexitmov si

,es

:[di] ;取第一單元中數(shù)組長(zhǎng)度;長(zhǎng)度*2=最后元素下標(biāo);形成最后元素地址;比較;<,則開(kāi)始查找;=為最后一個(gè)元素,退出;>最后元素,置CF=1,退出jmpshl si

,1add si

,dcmp

ax

,es:[si]jb

searchje

exitstcexitsearch:

mov starad,di ;將起始地址存入startadmov si

,es

:[di] ;取長(zhǎng)度

(si)evenr:jztest si

,1add

I;是偶數(shù)則第0位為1;當(dāng)ZF=1時(shí)則為全0,為;為奇數(shù)+1形成偶數(shù)inc

siaddi

addcompare:

cmpdi

,siax

,es:[di];形成查找元素的地址;比較(ax)=?es:[di]alldonehighersi

,2idxok:=則轉(zhuǎn)alldone;ax>則到高半部;si=2;不為2則繼續(xù)查找;CF=1,未找到j(luò)ejacmpjnenomatch:

stcjeidxok:alldoneshrsi

,1;(si)/2=’si’邏輯右0;為偶數(shù)嗎?;是;否則加1;再低半部,di-si形成subidx:jmphigher:test si

,1je

subidxinc

sisub di

,sishart

comparecmp si

,2;元素地址;在高半部nomatchsi

,2;未找到,置CF=1;(si)/2

(si)jeshrjmpshort

evenisi;轉(zhuǎn)eveni,將di+s高半部alldone:

movsi

,ddi

,startaddr 元素的位置

Sds 偏移位置movexit:

popretbsearch

endpcseg

endsend如果數(shù)組如下:List

Dw

12、11、22、33、44、55、66、77、88、99、111、222、333.要求查找的數(shù)為(ax)=55。數(shù)組長(zhǎng)度為12,第一次比較的是數(shù)組的第6個(gè)元素66;因55<66,所以第二次用低半部折半查找,比較的是第3個(gè)元素33;因55>33.所以第三次用高半部折半查找,比較的是第五個(gè)元素55.這樣經(jīng)過(guò)三次比較后,因查找成功而退出程序。如果要查找的數(shù)是(ax)=57.則第二次比較的仍是第六個(gè)元素66;因57<66,第二次用低半部折半查找,比較的是第三個(gè)元素33;因57>33,所以第三次用低半部折半查找,比較的是第五個(gè)元素55;因55<57,第四次用高半部折半查找,比較的又是第六個(gè)元素66;因57<66,在轉(zhuǎn)低半部查找時(shí),因(si)=2而以查找失敗退出程序。這個(gè)例子用CMP或TEST指令以及條件轉(zhuǎn)移指令產(chǎn)生兩個(gè)或多個(gè)程序分支。5.3.2用跳轉(zhuǎn)表實(shí)現(xiàn)多路分支在實(shí)現(xiàn)CASE結(jié)構(gòu)時(shí)還可以使用跳躍表法使程序能根據(jù)不同的條件轉(zhuǎn)移到多個(gè)程序分支去?!纠?7】設(shè)某程序有8路分支,試根據(jù)給定的N值(1~8),將程序的執(zhí)行轉(zhuǎn)移到其中的一路分支。程序流程如圖5.7所示。程序如下:DATA

SEGMENTTAB

DW

P1,P2,P3,P4,P5,P6,P7,P8NDB5S1DW?S2DW?S3DW?S4DW?S5DW?S6DW?S7DW?S8DW?DATAENDSSTACKSEGMENTSTACKCODEDB

200

DUP(0)ENDSSEGMENTASSUME

DS:DATA,SS:STACK,CS:START:

MOVAX,DATAMOV

DS,AXMOV

AL,NDEL

ALADD

AL,ALMOV

BL,ALMOV

BH,0JMP

TAB[BX]P1:MOVAX

,1MOVS1,AXJMPEXITP2:MOVAX

,2MOVS2,AXJMPEXITP3:MOVAX

,3MOVS3,AXJMPEXITP4:MOVAX

,4MOVS4,AXP5:

MOVAX

,5MOVS5,AXJMPEXITP6:

MOVAX

,6MOVS6,AXJMPEXITP7:

MOVAX

,7MOVS7,AXJMPEXITP8:

MOVAX

,8MOVS8,AXEXIT:MOVAH,4CHINT21HCODE

ENDSENDSTART上述程序中的無(wú)條件轉(zhuǎn)移指令的轉(zhuǎn)移地址采用的是變址尋址。同理,轉(zhuǎn)移地址也可以用寄存器間接尋址或基

址加變址尋址,讀者可自行考慮。返回本節(jié)5.4

循環(huán)程序設(shè)計(jì)循環(huán)程序的結(jié)構(gòu)單重循環(huán)程序設(shè)計(jì)多重循環(huán)程序設(shè)計(jì)返回本章首頁(yè)5.4.1循環(huán)程序的結(jié)構(gòu)1、循環(huán)程序的常見(jiàn)結(jié)構(gòu)形式如圖5.5(a(b)所示。循環(huán)有兩種結(jié)構(gòu)形式.一種是DO_WHILE形式;另一種是

DO_UNTIL形式。當(dāng)條件為真時(shí)執(zhí)行循環(huán)體,為假時(shí)跳出循環(huán)體。DO—WHILEDO—WHILE型把對(duì)循環(huán)條件的判斷放在循環(huán)的入口,先判斷條件,DO—UNTIL結(jié)構(gòu)則先執(zhí)行循環(huán)體,然后再判斷控制條件,不滿足則繼續(xù)執(zhí)行循環(huán)操作,一旦滿足循環(huán)條件則退出區(qū)別:DO—WHILE型有可能一次也不執(zhí)行循環(huán)體;DO—UNTIL型則至少執(zhí)行一次循環(huán)體;循環(huán)程序可由如下三部分組成:初始化部分循環(huán)體部分循環(huán)控制部分設(shè)置循環(huán)的初始狀態(tài);設(shè)置循環(huán)次數(shù)的計(jì)數(shù)值,以及為循環(huán)體正常進(jìn)行工作而建立的初始狀態(tài)。循環(huán)體這是工作的主體,它由循環(huán)的工作部分及修改部分組成。工作部分:完成程序功能。修改部分:保證每一次重復(fù)時(shí),參加執(zhí)行的信息能發(fā)生有規(guī)律的變化。循環(huán)控制部分程序設(shè)計(jì)的關(guān)鍵,控制循環(huán)的運(yùn)行和結(jié)束。5.4.2單重循環(huán)程序設(shè)計(jì)1.計(jì)數(shù)控制2.條件控制data

segmentary

dbcount

db

3sum

db

?next:

addyadd

si,loop

nextmovsum,

al例

計(jì)算

sum=1+2+3數(shù)據(jù)段定義:ary

db1,2,31,2,3si←Ary首地址cl←元素?cái)?shù),al←0和初值求和:al←al+[si],求下一元素地址si←si+1si,

ary

ncl,

counCtx-1且cx=0?data

ends……leamovmov

al,

0al,存累[s加i和]:sum←al1顯示累加和:sum結(jié)束例

計(jì)算

sum=1+2+3data

segmentarydb1,2,3countdb3sumdatadbends?segment

stack100

dup(0)endsstackdwstackcodemainsegmentproc

farassume

cs:code,ds:data,ss:stackstart:

mov

ax,

datamov

ds,

axnext:nextsum,

almaincodelea

si,

arymov

cl,

countmov

al,

0add

al,

[si]add

si,

1loopmovmov

al,

sumadd

al,

30hmov

dl,

almov

ah,

2int

21hmov

ah,

4chint

21hendpendsend

start1.計(jì)數(shù)控制【例5.7】已知有幾個(gè)元素存放在以BUF為首址的字節(jié)存貯區(qū)中,試統(tǒng)計(jì)其中正元素的個(gè)數(shù)。顯然,每個(gè)元素為一個(gè)8位有符號(hào)二進(jìn)制數(shù),統(tǒng)計(jì)其中正元素的個(gè)數(shù)可用循環(huán)程序?qū)崿F(xiàn)。其程序流程圖如圖5.6所示。LEABX,BUFMOV

CX,NBYTE

PTR

[BX]L2MOV

AX,

0L1:

MOV

DL

,CMP

DL

,

0JLEINC

AX

;正元素個(gè)數(shù)L2:

INC

BX

;BX←元素地址+1LOOP

L1

MOV

NUM,AXDATASEGMENTBUFDB 1,3,5,,0,-1,-3,-5,NEQU $-BUFNUMDW

?DATAENDSSTACK

SEGMENT

STACKDB

200

DUP(0)STACKCODEENDSSEGMENTASSUME

DS:DATA,CS:CODE,SS:STACKSTART:MOVMOVLEAMOVAX

,

DATADS,

AXBX,

BUFCX,

N;元素起始地址;元素總個(gè)數(shù)值=0MOVAX,

0;正元素個(gè)數(shù)初L1:MOV

DL,BYTE

PTR

[BX]CMPDL

,

0JLEL2INCAX;正元素個(gè)數(shù)L2:向下一個(gè)元素INCBX;BX←元素地址+1,指LOOP

L1

;

DEC

CX;

JNEL1

;MOV

NUM,

AXMOV

AH,

4CH【例5.8】字符串比較【例5.8】試編寫一程序,要求比較兩個(gè)字符串STR1和STR所含字符是否相同,若相同則顯示‘MATCH!’,若不相同則顯示‘NO

MATCH!’。(程序略)其流程圖如圖5.7所示。程序data

segmentstring1MATCH

NOMATCHDB

"abcde"DB

"MATCH$"db

"no

match$"dataextraendssegmentstring2numdb

"abcde"db

"ok"extra

endsprogname

segmentmainproc

farassumecs:progname,ds:data,es:extrastart:pushmovpushmov

mov

mov

mov

movdsax,0axax,datads,axax,extraes,axal,match-string1;字符串1元素個(gè)數(shù)cmpjnelealeamoval,num-string2dispnosi,string1di,string2cx,match-string1rota:moval,[si]cmpal,[di]jnedispnoincsiincdilooprotadispma:movdx,offsetmatchmovah,9int21hjmpexitdispno:movdx,offsetnomatchmovah,9int21hexit:

retmain

endpprognameends

end

start例5.11、在ADDR單元中存放著數(shù)Y的地址,試編制一程序,把Y中1的個(gè)數(shù)存入COUNT單元中。要測(cè)出Y中1的個(gè)數(shù),就應(yīng)逐

位測(cè)試,一個(gè)比較簡(jiǎn)單的辦法是可根據(jù)最高有效位是否為1來(lái)計(jì)數(shù),然后用移位的方法把各位數(shù)逐次移到最高位去。循環(huán)的結(jié)束可以用計(jì)數(shù)值為16來(lái)控制,但更好的辦法是結(jié)合上述方法可以用測(cè)試數(shù)是否為0來(lái)作為結(jié)束條件,這樣可以在很多情況下縮短程序的執(zhí)行時(shí)間。2.條件控制例5.11、在ADDR單元中存放著數(shù)Y的地址,試編制一程序,把Y中1的個(gè)數(shù)存入COUNT單元中。要測(cè)出Y中1的個(gè)數(shù),就應(yīng)逐

位測(cè)試,一個(gè)比較簡(jiǎn)單的辦法是可根據(jù)最高有效位是否為1來(lái)計(jì)數(shù),然后用移位的方法把各位數(shù)逐次移到最高位去。循環(huán)的結(jié)束可以用計(jì)數(shù)值為16來(lái)控制,但更好的辦法是結(jié)合上述方法可以用測(cè)試數(shù)是否為0來(lái)作為結(jié)束條件,這樣可以在很多情況下縮短程序的執(zhí)行時(shí)間。例5.11、在ADDR單元中存放著數(shù)Y的地址,試編制一程序,把Y中1的個(gè)數(shù)存入COUNT單元中。DataAddrsegmentdwnumberNumberdw1100110011110000BCountdw?DataPrognamendssegmentMainproc

farAssameStart:

Mov

ax,

dataMov

ds,

axMovMovMovcx,

0

;bx,

addrax,

[bx];

ax

=

offffRepeat:jztest

ax,

offfffhexit

;為零則exit,ZF=1ax正數(shù)則轉(zhuǎn)移(非負(fù))shift:;

邏輯左移,最右添0exit:jns

shift

;inc

cxshl

ax

,1jmp

repeatcount

,cxmov

dl,

clmov

ah,

2mov

ah,4ch這個(gè)例子說(shuō)明算法和循環(huán)控制條件的選擇對(duì)程序的工作效率影響很大。在編程時(shí),應(yīng)據(jù)具體情況來(lái)確定循環(huán)控制條件。第二種解法:【例5.11】試編一個(gè)程序?qū)⒆謫卧狟UF中所含1的個(gè)數(shù)存入COUNT單元中。要測(cè)出BUF字單元所含1的個(gè)數(shù),首先將BUF中的數(shù)送給寄存器AX,然后將AX寄存器邏輯左移一次,如果CF=1,則表明AX中的最高位為1,則計(jì)數(shù)器CL計(jì)數(shù)1次,如果CF=0,表明AX最高位為0,這樣依次將最高位移入CF中去測(cè)試。移位之后,判斷AX的值是否為0,如果為0則結(jié)束循環(huán),不為0,則繼續(xù)循環(huán)。其流程圖如圖5.8所示。程序如下:STACK

SEGMENT

STACKDB

200

DUP(0)STACK

EDNSDATA

SEGMENTDWBUF0011110010101011BCOUNTDB

?DATACODEENDSSEGMENTASSUME

DS:DATA,CS:CODE,SS:STACKSTART:MOV

AX,DATAMOV

DS,AXMOV

AX,BUFMOV

CL,0;計(jì)數(shù)器為0;(AX)=0,結(jié)束循環(huán)LOPA:

CMP

AX,0JE

EXITSHL

AX,1;AX左移一位JNC

LOPAINC

CL;產(chǎn)生進(jìn)位,(CL)+1→CLJMP

LOPAEXIT:

MOV

COUNT,CLMOV

AH,4CHINT

21H3、循環(huán)條件設(shè)計(jì)方法綜合舉例例5.10、試編制一個(gè)程序把BX寄存器內(nèi)的二進(jìn)制數(shù)用十六進(jìn)制數(shù)的形式在屏幕上顯示出來(lái)。把BX的內(nèi)容從左到右每4位為一組在屏幕上顯示出來(lái),顯然這可以用循環(huán)結(jié)構(gòu)來(lái)完成,每次循環(huán)顯示一個(gè)十六進(jìn)制數(shù)位,因而循環(huán)次數(shù)是已知的,BX中存放十六個(gè)二進(jìn)制數(shù)位,故計(jì)數(shù)值為4。程序中用CH寄存器存放循環(huán)計(jì)數(shù)值:CH=

4,而用DEC及JNZ兩條指令完成循環(huán)計(jì)數(shù)功能;因?yàn)檠h(huán)移位要用CL寄存器,而LOOP指令也要使用CX,故循環(huán)不用LOOP語(yǔ)句。BX

0011,0110,0011,0111

顯示為3637HBX

0110,0011,

0111,

0011

BL

0111,0011,左移4次and

al,ofH;00110000,

1111

al

0110000,

0011

al

0000,0011add

al,30H0011,00000011,0011al例1

將BX寄存器中的內(nèi)容以十六進(jìn)制形式顯示出來(lái)?!鳥(niǎo)X是一個(gè)16位寄存器二進(jìn)制

1010

1001

0011

1110▲用十六進(jìn)顯示時(shí),每4位用一個(gè)字符顯示,共4個(gè)其中:

0000

→’0’30H

,1010

→’A’

41H0001

→’1’31H

,1011

→’B’

42H、、、、1001

→’9’39H

,1111

→’F’

46H?‘E’十六進(jìn)制A9

3E屏幕上的顯示對(duì)應(yīng)的ASCII‘A’

‘9’41H

39H

33H‘3’45H0000

0001B

+

30H=

31H0001B

‘1’0000

1001B

+

30H=39H1001B‘9’(2)對(duì)于1010~1111(A~F),先擴(kuò)展成一個(gè)字節(jié),高4位清0,加上30H后,還要再加上07H,才能得到’A’~’F’對(duì)應(yīng)的ASCII碼0000

1010B+30H+07H

=

41H1010B

‘A’0000

1111B+30H+07H

=46H1111B‘F’算法:取出要顯示的某4位,轉(zhuǎn)換為對(duì)應(yīng)的ASCII碼,再調(diào)用DOS系統(tǒng)功能進(jìn)行顯示。(1)對(duì)于0000~1001(0~9),先擴(kuò)展成一個(gè)字節(jié),高4位清0,加上30H后,即可得字符’0’~’9’對(duì)應(yīng)的ASCII碼。這里采用了循環(huán)移位的方法,把所有顯示的四位二進(jìn)制數(shù)移到最右面,以便作數(shù)字到字符的轉(zhuǎn)換工作。另外由于數(shù)字0~9的ASCII為30~39H,而字母A~F的ASCII為41~46H,所以在把四位二進(jìn)制數(shù)加上30H后還需做一次判斷,如果為字符A~F,則還應(yīng)加上7才能顯示出正確的十六進(jìn)制數(shù)二進(jìn)制到十六進(jìn)制轉(zhuǎn)換C顯示字符個(gè)數(shù)CH=4循環(huán)移位次數(shù)CL=4BX循環(huán)左移4位,將要顯示的值移至低4位,保存在DL中清DL的高4位,

只保留要顯示位的值DL

DL+30H完成數(shù)值0~9的ASCII碼轉(zhuǎn)換N完成數(shù)值A(chǔ)~F的ASCII碼轉(zhuǎn)換用02功能顯示DL中的字符NDL超出39H?YDL←DL+07HCH←CH-1轉(zhuǎn)換結(jié)束?YRET返回list_bx

PROCMOV

CH,

4MOV

CL,

4next:ROL

BX,

CLMOV

DL,

BLAND

DL,

0FHADD

DL,

30HCMP

DL,

39HJLE

printADD

DL,

07Hprint:MOV

AH,

2HINT

21HDEC

CHJNZ

nextRET

;子程返回ENDPlist_bxcodeENDSEND

start例5.10、試編制一個(gè)程序把BX寄存器內(nèi)的二進(jìn)制數(shù)用十六進(jìn)制數(shù)的形式在屏幕上顯示出來(lái)。data

segmrntcount

dw

3637Hdata

endsprognam

segmentMain

proc

farassumestart:

pushcs:

prognam,ds:datadssub

ax,

axpush

axmov

bx,

countmov

ch,4;共顯示4位數(shù).next:

movrolmovcl,

4

;

計(jì)數(shù)為4.bx,

cl;

左移4次.dl,

bl

;

得到8位

ALanddl,ofh;取低4位.adddl,30h;變?yōu)锳SCII碼cmpdl,3ah

;

>9

?.jl

print

;

小于34h……add

dl,

07hPrint:Mov

ah,2;Ascii

dl,調(diào)中斷顯示Int21

h;Decch;顯示4位嗎?Jnz

nextRet;再執(zhí)行顯示二位.←

①mov

Ax,4c00h②Int21HMain

endpPrognam

ends例5.15、設(shè)有數(shù)組X和Y。X數(shù)組中有X1到X10;Y數(shù)組中有Y1到Y(jié)10;試編程計(jì)算:Z1=X1+Y1;

Z2=X2+Y2;

Z3=X3-Y3;Z4=X4-Y4;

Z5=X5-Y5;Z6=X6+Y6;Z7=X7-Y7;

Z8=X8-Y8;

Z9=X9+Y9;Z10=X10+Y10。結(jié)果存入Z數(shù)組,對(duì)于這種問(wèn)題,我們也可用循環(huán)來(lái)完成;已知循環(huán)計(jì)數(shù)值為10,每次循環(huán)的操作數(shù)是可以順序取出的,但所做的操作卻有不同,這里有兩種操作:加、減,為了區(qū)別每次應(yīng)該做那一種操作,可以設(shè)置標(biāo)志位,如標(biāo)志為0作加法;為1則做減法,這樣進(jìn)入循環(huán)后只要判別標(biāo)志位,就可確定應(yīng)該做的操作了。把10次操作設(shè)立10個(gè)標(biāo)志位,我們把它放在一個(gè)存儲(chǔ)單元LOG中,這種存儲(chǔ)單元一般稱為邏輯尺,本例設(shè)定邏輯尺為:0000

0000

1101

1100從低位開(kāi)始所設(shè)的標(biāo)志位反映了每次要做的操作順序,最高的6位沒(méi)有意義,設(shè)為0。Zi=Xi+Yi4

s3s2s

1I=10s9s

8s

7s6s5s+操作設(shè)立10個(gè)標(biāo)志位0+,--+-,--++10次0,1101,1100位=16

15

14

13s12

11

10

9s

8

7

6

5s3

2

1字:0

0

0

0

0

0

0

0,1

1

0

1,1

1

0

0=

0DCHZ1=X1+Y1;

Z2=X2+Y2;

Z3=X3-Y3;Z4=X4-Y4;Z5=X5-Y5;

Z6=X6+Y6;Z7=X7-Y7;Z8=X8-Y8;Z9=X9+Y9;

Z10=X10+Y10mov

bx,0mov

cx,10logmov

dx,next:

movax,

x[bx]shrdx

,

1jcsubtaddax,

y[bx]datasegment;數(shù)據(jù)段xdw2,3,4,5,6,7,8,9,10,11;ydw1,2,3,4,5,6,7,8,9,10;Zdw10dup(?);logdw00dchdataends;代碼段prognammainprocsegmentfarassumecs:prognam,ds:datastart:pushdssubpushmova;初始化movax,

axaxax,

datds,

axnext:mov

bx,

0mov

cx,

10mov

dx,

logmov

ax,

x[bx];循環(huán)shr

dx

,

1jc

subtadd

ax,

y[bx]jmp

shortresultsubt:result:sub

ax

,

y[bx]mov

z[bx],axadd

bx

,2nextloopretmainprognamendpendpend例5.13、在附加段中,有一個(gè)首地址為list和未經(jīng)排序的字?jǐn)?shù)組,在數(shù)組的第一個(gè)字中存放著數(shù)組的長(zhǎng)度,數(shù)組的首地址已存放在DI寄存器中。AX寄存器中存放著一個(gè)數(shù)。要求編制一程序;在數(shù)組中查找該數(shù),如果找到該數(shù)則把它從數(shù)組中刪除。分析:1、首先查找數(shù)組中是否有(AX),如果沒(méi)有則不對(duì)數(shù)組做任何處理就結(jié)束程序;2、如果找到這一元素則應(yīng)把數(shù)組中地址比該元素高(其前)的元素向低地址方向移動(dòng)(后移一個(gè)

字),并修改數(shù)組長(zhǎng)度值;3、如果找到的元素恰好位于數(shù)組的末尾,則不必移動(dòng)任何元素,只要修改數(shù)組長(zhǎng)度就可以了;所以程序第一部分——查找元素可以使用串處理命令;第二部分——?jiǎng)h除元素則可以使用循環(huán)結(jié)構(gòu),因?yàn)椴檎医Y(jié)束時(shí)就可以知道該元素的位置,所segment‘personalDatareaMess

dbcomputer$’DatareaExtraListExtraendssegmentdw

5,

1,

2,

3,

4,

6endsCodeMainprocnear]segmentproc

far

;

[del_ulAssumc

cs:

code

,

ds:

datarea,

es:extraStart:PushdsSubax,axPushaxMovax,datareaMovds

,axlistMov

di

,

offsetCldMovax,2

;要?jiǎng)h除的數(shù)為2Push

diMov

cx

,es

:

[di];元素個(gè)數(shù)5→

cxdi

,2;每個(gè)元素ax,

es:[di];

←RepneLop:Add占兩個(gè)字節(jié)cmpscaswJe

delete;找到轉(zhuǎn)deletedec

cxjnz

lopDelete:

jcxe

deccntNextel:mov

bx

,es

:

[di]Mov

es:

[di-2],

bxAdd

di

,2Loop

NextelDeccnt:

pop

didec

word

ptr

es:[di]Exit:

retMain

endp[

del_ulendp]Code

endsEnd

start用子程序方法編制程序如下:del_ul

proc

farCld

Push

di;DF=0時(shí),向前查找。;右起始地址;Mov

cx,

es:[di] ;

取元素?cái)?shù);Add

di

,

2 ;

改變指針。Repne

scaswJz

delete

;結(jié)果為0,ZF=1.轉(zhuǎn),此時(shí)CX值

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論