版權(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
;
小于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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年上網(wǎng)課學(xué)習(xí)心得體會(huì)(3篇)
- 課題申報(bào)參考:教育數(shù)字化轉(zhuǎn)型下高校輔導(dǎo)員數(shù)字素養(yǎng)測(cè)評(píng)及提升路徑研究
- 2025年度個(gè)人商鋪長(zhǎng)期租賃合同標(biāo)的物詳細(xì)清單3篇
- 2025年度個(gè)人肖像權(quán)授權(quán)使用協(xié)議書個(gè)人肖像權(quán)體育賽事推廣授權(quán)3篇
- 二零二五年度出租房屋消防安全設(shè)施改造施工合同4篇
- 二零二五年度假離婚法律風(fēng)險(xiǎn)評(píng)估及解決方案合同3篇
- 2025年度無(wú)人機(jī)租賃合同協(xié)議書8篇
- 2025版木工預(yù)制構(gòu)件生產(chǎn)與安裝合同范本4篇
- 個(gè)人合同擔(dān)保書(2024年樣本):教育貸款擔(dān)保2篇
- 2025年個(gè)人挖機(jī)租賃合同續(xù)簽協(xié)議4篇
- 2025水利云播五大員考試題庫(kù)(含答案)
- 老年髖部骨折患者圍術(shù)期下肢深靜脈血栓基礎(chǔ)預(yù)防專家共識(shí)(2024版)解讀
- 中藥飲片驗(yàn)收培訓(xùn)
- 手術(shù)室??谱o(hù)士工作總結(jié)匯報(bào)
- DB34T 1831-2013 油菜收獲與秸稈粉碎機(jī)械化聯(lián)合作業(yè)技術(shù)規(guī)范
- 創(chuàng)傷處理理論知識(shí)考核試題及答案
- 肝素誘導(dǎo)的血小板減少癥培訓(xùn)課件
- 抖音認(rèn)證承諾函
- 高等數(shù)學(xué)(第二版)
- 四合一體系基礎(chǔ)知識(shí)培訓(xùn)課件
- ICD-9-CM-3手術(shù)與操作國(guó)家臨床版亞目表
評(píng)論
0/150
提交評(píng)論