計算機(jī)IBM-PC匯編語言程序設(shè)計課件_第1頁
計算機(jī)IBM-PC匯編語言程序設(shè)計課件_第2頁
計算機(jī)IBM-PC匯編語言程序設(shè)計課件_第3頁
計算機(jī)IBM-PC匯編語言程序設(shè)計課件_第4頁
計算機(jī)IBM-PC匯編語言程序設(shè)計課件_第5頁
已閱讀5頁,還剩79頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第五章循環(huán)與分支程序設(shè)計5.1循環(huán)程序設(shè)計5.2分支程序設(shè)計5.3如何在實(shí)模式下發(fā)揮80386及其后繼機(jī)型的優(yōu)勢第五章循環(huán)與分支程序設(shè)計5.1循環(huán)程序設(shè)計1

1.編寫匯編語言程序步驟l

分析實(shí)際問題,確定解決問題的算法l

按算法畫出程序流程圖l

按流程圖編寫程序l上機(jī)調(diào)試,運(yùn)行程序注:本教材所討論的編程環(huán)境只限于在DOS操作系統(tǒng)下的實(shí)模式

1.編寫匯編語言程序步驟注:本教材所討論的編程環(huán)境只限于22.判斷程序質(zhì)量的標(biāo)準(zhǔn)程序的正確性程序的可讀性程序的執(zhí)行時間程序所占內(nèi)存大小2.判斷程序質(zhì)量的標(biāo)準(zhǔn)33.幾種程序結(jié)構(gòu)順序結(jié)構(gòu)循環(huán)結(jié)構(gòu)分支結(jié)構(gòu)子程序結(jié)構(gòu)3.幾種程序結(jié)構(gòu)4順序結(jié)構(gòu)形式順序結(jié)構(gòu)形式5循環(huán)結(jié)構(gòu)形式當(dāng)型循環(huán)(當(dāng)條件成立進(jìn)入循環(huán))循環(huán)初始設(shè)置循環(huán)體循環(huán)條件判斷?YN直到型循環(huán)(直到條件成立退出循環(huán))YN循環(huán)初始設(shè)置循環(huán)體循環(huán)條件判斷?循環(huán)結(jié)構(gòu)形式當(dāng)型循環(huán)循環(huán)初始設(shè)置循環(huán)體循環(huán)條件判斷?YN直到6兩個分支YN

、、、CMPAL,BLJGgreat

JMPexitgreat:

exit:、、、、、、

AL≤BL處理AL>BL處理分支結(jié)構(gòu)形式兩個分支YN、、、AL≤BL處理AL>BL處7三個分支

、、、CMPAL,0

JGgreat

JLless

JMPexitless:

JMPexitgreat:

exit:、、、AL=0處理AL>0處理AL<0處理YYNN分支結(jié)構(gòu)形式……三個分支、、、AL=0處理AL>0處理AL81.多處調(diào)用完成同一功能的子程:codeSEGMENTstart:、、

CALLsubp、、

CALLsubp、、

CALLsubp、、MOVAH,4CHINT21HsubpPROC、、、、RETsubpENDPcodeENDSENDstart2.模塊化程序設(shè)計:codeSEGMENTbegin:CALL

sub1

CALLsub2

CALLsub3MOVAH,4CHINT21Hsub1PROC、、RETsub1ENDPsub2PROC、、RETsub2ENDPsub3PROC、、RETsub3ENDPcodeENDSENDbegin

子程結(jié)構(gòu)形式注意返回DOS語句位置1.多處調(diào)用完成同一功能的子程:2.模塊化程序設(shè)計:子程結(jié)構(gòu)9開

始結(jié)

化循環(huán)的初始狀態(tài)

環(huán)

體循環(huán)的工作部分及修改部分

控制條件

計數(shù)控制特征值控制地址邊界控制5.1.1循環(huán)程序的結(jié)構(gòu)形式5.1循環(huán)程序設(shè)計(1)DO-WHILE結(jié)構(gòu)(2)DO-UNTIL結(jié)構(gòu)開始結(jié)束初始化10有關(guān)字符、數(shù)碼轉(zhuǎn)換的處理1.計算機(jī)處理字符時,常用的字符編碼是ASCII碼。2.數(shù)字和字母的ASCII碼是一個有序序列數(shù)字0~9:30H~39H大寫字母A~Z:41H~5AH小寫字母a~z:61H~7AH5.1.2循環(huán)程序設(shè)計方法例5.1將寄存器BX中的內(nèi)容以十六進(jìn)制形式顯示出來。 有關(guān)字符、數(shù)碼轉(zhuǎn)換的處理5.1.2循環(huán)程序設(shè)計方法例5.11BX是一個16位寄存器二進(jìn)制1010100100111110

用十六進(jìn)顯示時,每4位用一個字符顯示,共4個其中:0000→’0’30H,1010→’A’41H

0001→’1’31H,1011→’B’42H、、、、

1001→’9’39H,1111→’F’46H?十六進(jìn)制A93E屏幕上的顯示‘A’‘9’‘3’‘E’對應(yīng)的ASCII41H39H33H45HBX是一個16位寄存器用十六進(jìn)顯示時,每4位用一個字符顯12BX1234BX113算法:取出要顯示的某4位,轉(zhuǎn)換為對應(yīng)的ASCII碼,再調(diào)用DOS系統(tǒng)功能進(jìn)行顯示。(1)對于0000~1001(0~9),先擴(kuò)展成一個字節(jié),高4位清0,加上30H后,即可得字符’0’~’9’對應(yīng)的ASCII碼。00000001B+30H=31H00001001B+30H=39H

0001B‘1’1001B‘9’(2)對于1010~1111(A~F),先擴(kuò)展成一個字節(jié),高4位清0,

加上30H后,還要再加上07H,才能得到’A’~’F’對應(yīng)的ASCII碼00001010B+30H+07H=41H00001111B+30H+07H=46H

1010B‘A’1111B‘F’算法:(1)對于0000~1001(0~9),先擴(kuò)展14codeSEGMENTASSUMECS:codestart:MOVCH,4;字符個數(shù)rotate:MOVCL,4;循環(huán)移位次數(shù)

ROLBX,CL

;取顯示位的值

MOVAL,BL

;保存在AL中

ANDAL,0FH

;清除高4位

ADDAL,30H

;轉(zhuǎn)變?yōu)閿?shù)字的ASCII

CMPAL,3aH;大于3aH,則應(yīng)轉(zhuǎn)變

JLprint;為數(shù)字0~9的ASCII

ADDAL,07H;為字母A~F的ASCIIprint:MOVDL,AL;送

ASCII字符到DLMOVAH,2;顯示DL中的字符INT21HDECCH;顯示結(jié)束?

JNZnextMOVAH,4CH;返回DOSINT21HcodeENDS

ENDstart顯示字符個數(shù)CH=4循環(huán)移位次數(shù)CL=4BX循環(huán)左移4位,將要顯示的值移至低4位,保存在AL中清AL的高4位,只保留要顯示位的值A(chǔ)L←AL+30H完成數(shù)值0~9的ASCII碼轉(zhuǎn)換YNAL←AL+07H完成數(shù)值A(chǔ)~F的ASCII碼轉(zhuǎn)換用02功能顯示DL中的字符YN返回DOSAL超出39H?CH←CH-1轉(zhuǎn)換結(jié)束?開始codeSEGMENT顯示字符個數(shù)CH=4BX循環(huán)左15例5.2在ADDR單元中存放著數(shù)Y,度編制一程序把Y中1的個數(shù)存入COUNT單元中。datareasegment addredw1234h countdw?datareaends movcx,0 movbx,addre movax,bxagain: testax,0ffffh jzexit jnsshift inccxshift: shlax,1 jmpagainexit: movcount,cx ret 例5.2在ADDR單元中存放著數(shù)Y,度編制一程序把Y中116例5.4

將正數(shù)n插入一個已整序的字?jǐn)?shù)組的正確位置。

xdw?array_headdw3,5,15,23,37,49,52,65,78,99array_enddw105ndw32movax,nmovarray_head-2,0ffffhmovsi,0compare:cmparray_end[si],axjleinsertmovbx,array_end[si]movarray_end[si+2],bxsubsi,2jmpshortcompareinsert:movarray_end[si+2],ax

-1

3

5

49

15

52

23

37

105

99

78

65

32xn例5.4將正數(shù)n插入一個已整序的字?jǐn)?shù)組的正確位置。17例5.5Zi=Xi+Yi

LOGIC_RULE DW 00DCH …… MOV BX,0 MOV CX,10 MOV DX,LOGIC_RULENEXT: MOV AX,X[BX]

SHR DX,1

JC SUBTRACT ADD AX,Y[BX] JMP SHORTRESULTSUBTRACT: SUB AX,Y[BX]RESULT: MOV Z[BX],AX ADD BX,2 LOOP NEXT RET ……例5.5Zi=Xi+Yi LOGIC_RULE DW 18例5.6鍵入一行以空格開頭以空格結(jié)束的字符串datareasegment buffer db80dup(?) flag db?datareaends leabx,buffer movflag,0next: movah,01;讀鍵盤 int21h;所讀內(nèi)容放入al testflag,01h;flag=1? jnzfollow;flag=0,zf=1不轉(zhuǎn) cmpal,20h;al是空格? jnzexit;不是,zf=0退出 movflag,1;置標(biāo)志flag=1 jmpnextfollow: cmpal,20h;al是空格? jzexit;是,zf=1,退出 mov[bx],al;不是,保存 incbx;數(shù)組索引加1 jmpnextexit:20abcdef20flag=01jzexit成立例5.6鍵入一行以空格開頭以空格結(jié)束的字符串datare195.1.3多重循環(huán)程序設(shè)計基本方法與單重循環(huán)相同,但要注意:1、分別考慮各重循環(huán)的控制條件及其程序?qū)崿F(xiàn),相互之間不能混淆2、每次從外層循環(huán)再次進(jìn)入內(nèi)層循環(huán)時,初始條件要重新設(shè)置5.1.3多重循環(huán)程序設(shè)計基本方法與單重循環(huán)相同,但要注意20例5.7

將首地址為a的字?jǐn)?shù)組從大到小排序(氣泡算法,多重循環(huán))

adw100,30,78,99,15,-1,66,54,189,256movcx,10;待排序數(shù)的個數(shù)deccx;外循環(huán)的次數(shù)loop1:movdi,cx;暫存外循環(huán)次數(shù)movbx,0;數(shù)組下標(biāo)loop2:movax,a[bx];取第bx個數(shù)cmpax,a[bx+2];與后一個數(shù)比較jgecontinue;[bx]>=[bx+2]xchgax,a[bx+2];<,則交換位置mova[bx],axcontinue:addbx,2;指向下一個數(shù)looploop2

movcx,di;恢復(fù)外循環(huán)次數(shù)looploop1例5.7將首地址為a的字?jǐn)?shù)組從大到小排序(氣泡算法,多重循21例5.8附加段字?jǐn)?shù)組首地址存于DI,第1字存放長度,從小到大排序

extrasegment

adw10,10h,12h,32h,21h,11h,56h,43h,33h,3h,67h

extraendsdatasegment start_addrdw? save_cntdw?dataends leadi,a;取有效地址 movstart_addr,di movcx,es:[di];取長度 movsave_cnt,cx;數(shù)組長度init: movbx,1;結(jié)束標(biāo)志 decsave_cnt jzsorted;zf=1,轉(zhuǎn)移 movcx,save_cnt movdi,start_addrnext: adddi,2 movax,es:[di];取數(shù) cmpes:[di+2],ax;比較 jaecont;>=,轉(zhuǎn)移,不換 xchges:[di+2],ax moves:[di],ax subbx,bx;排序標(biāo)志cont: loopnext cmpbx,0;bx=1,已排好 jeinitsorted: movdi,start_addr例5.8附加段字?jǐn)?shù)組首地址存于DI,第1字存放長度,從小到22練習(xí)5.11:從鍵盤輸入一系列以$結(jié)束的字符串,統(tǒng)計數(shù)字字符的個數(shù)datasegment countdw0 buffdb50dup(?)dataendsprognamsegmentmainprocfar assumecs:prognamstart: pushds subax,ax pushax movax,data movds,ax leabx,buff;取緩沖地址input: movah,01;從鍵盤讀串 int21H;存入al中 mov[bx],al;保存字符 incbx;buff數(shù)組下標(biāo) cmpal,‘$‘;是不是$ jnzinput;是,結(jié)束讀 leabx,buff;取串地址 movax,0next: movcl,[bx];取串中字符 incbx;指向下一字符 cmpcl,‘$’;是不是$ jzdisp;是,zf=1,轉(zhuǎn)移 cmpcl,30h;與’0’比較 jbcont;<‘0’,不計數(shù) cmpcl,39h;與’9’比較 jnbenext;>’9’,不計數(shù) incax;計數(shù)cont: jmpnextdisp: ret mainendpprognamends endstart練習(xí)5.11:從鍵盤輸入一系列以$結(jié)束的字符串,統(tǒng)計數(shù)字字符23練習(xí)5.11:測試一字符串是否存在數(shù)字,若存在,置CL第5位置1,否則置0datasegmentstringdb'abcqdefghijklmnopqrs'dataendsprognam segmentmainprocfarassumecs:prognam,ds:data,es:datastart:pushdssubax,axpushaxmovax,datamovds,axmoves,axbegin: movcx,20;字符個數(shù) movsi,0;數(shù)組下標(biāo)again: moval,string[si] cmpal,30h;與’0’比較 jbgoon;<,轉(zhuǎn)移 cmpal,39h;與‘9’比較 jagoon;>,轉(zhuǎn)移 orcl,20h;有數(shù)字,置5位 jmpexitgoon: incsi;數(shù)組下標(biāo)加1 loopagain andcl,0dfh;無數(shù)字,清5位exit: ret mainendpprognamends endstart練習(xí)5.11:測試一字符串是否存在數(shù)字,若存在,置CL第5位24循環(huán)程序設(shè)計小結(jié)1、循環(huán)控制條件的選擇: a.循環(huán)次數(shù)已知,采用LOOP b.循環(huán)次數(shù)已知,但有可能使用其他特征或條件結(jié)束循環(huán), 可采用LOOPZ和LOOPNZ c.循環(huán)次數(shù)未知,具體問題具體分析2、設(shè)立條件標(biāo)志位的方法循環(huán)程序設(shè)計小結(jié)255.2分支程序設(shè)計5.2.1分支程序的結(jié)構(gòu)形式雙分支與多分支的共同特點(diǎn):運(yùn)行方向是向前的在某一種特定條件下,只能執(zhí)行其中的一個分支5.2.1分支程序設(shè)計方法1、使用CMP、TEST等運(yùn)算型指令+條件轉(zhuǎn)移指令2、使用邏輯尺的方法3、使用跳躍表法實(shí)現(xiàn)CASE結(jié)構(gòu)5.2分支程序設(shè)計5.2.1分支程序的結(jié)構(gòu)形式雙分支與26例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1dsegsegmentlow_idxdw ?high_idxdw ?listdw12,11,22,33,44,55,66,77,88,99,111,222,333targetdw 77dsegendscsegsegmentmainprocfar assumecs:cseg,ds:dseg,es:dsegstart: pushds subax,ax pushax movax,dseg movds,ax moves,ax例5.9折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長27例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1 movax,target ; leadi,list;取數(shù)組首地址 cmpax,es:[di+2];取第1個數(shù) jachk_last ;>第1個,檢查最后1個 leasi,es:[di+2];<=第1個 jeexit ;=,退出 stc ;CF=1,沒找到 jmpexitchk_last:movsi,es:[di] ;下面三條使SI指向

shlsi,1 ;數(shù)組末元素

addsi,di cmpax,es:[si] ;與末元素比較 jbsearch ;<,搜索數(shù)組 jeexit ;=,退出 stc ;CF=1,沒找到 jmpexit0400list100102104106108例5.9折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長28例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1search: movlow_idx,1 ;搜索開始的地方 movbx,es:[di] ;數(shù)組長度 movhigh_idx,bx ;搜索結(jié)束的地方 movbx,di ;list地址mid: movcx,low_idx ; movdx,high_idx ;

cmpcx,dx ;比較’頭’與’末’指針 jano_match ;>,’頭’到’末’之后 addcx,dx ;以下三條計算 shrcx,1 ;’頭’與’末’的中點(diǎn) movsi,cx

shlsi,1 ;對準(zhǔn)中間’字’0500100102104106108list10A(1+5)/2=33*2=6DI偏移6,即106,即第3字例5.9折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長29compare: cmpax,es:[bx+si] ;比較,bx指向數(shù)組首元素 jeexit ;=,找到,退出 jahighter ;>,調(diào)節(jié)搜索’頭’ deccx ;<= movhigh_idx,cx ;調(diào)節(jié)搜索’末’ jmpmidhighter: inccx movlow_idx,cx ;調(diào)節(jié)搜索’頭’ jmpmidno_match: stcexit: ret例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1compare:例5.9折半查找:附加段有一個有序字?jǐn)?shù)組30例5.10

根據(jù)AL寄存器中哪一位為1(從低位到高位)把程序轉(zhuǎn)移到8個不同的程序分支去。branch_tabledwroutine1

dwroutine2

dwroutine3

dwroutine4

dwroutine5

dwroutine6

dwroutine7

dwroutine8注意:DW標(biāo)號的使用例5.10根據(jù)AL寄存器中哪一位為1(從低位到高位)把程31寄存器間接尋址cmpal,0jecontinueleabx,branch_tableL

:shral,1;邏輯右移,最低位進(jìn)入CF位jnbnot_yet

;jnb=jnc,CF=0,轉(zhuǎn)移jmpwordptr[bx]

;段內(nèi)間接轉(zhuǎn)移not_yet:addbx,typebranch_tablejmpLcontinue:……routine1:……routine2:…………調(diào)試源程序寄存器間接尋址cmpal,0調(diào)試源程序32變址尋址方式實(shí)現(xiàn)cmpal,0jecontinuemovsi,0

L

:shral,1 ;邏輯右移,最低位進(jìn)入CF位jnbnot_yet

;jnb=jnc,CF=0,轉(zhuǎn)移jmpbranch_table[si]

;段內(nèi)間接轉(zhuǎn)移not_yet:addsi,typebranch_tablejmpLcontinue:……routine1:……routine2:…………調(diào)試源程序變址尋址方式實(shí)現(xiàn)cmpal,0調(diào)試源程序33基址變址尋址cmpal,0jecontinueleabx,branch_tablemovsi,7*typebranch_tablemovcx,8L

:shlal,1 ;邏輯左移,最高位進(jìn)入CF位jnbnot_yet

;jnb=jnc,CF=0,轉(zhuǎn)移jmpwordptr[bx][si]

;段內(nèi)間接轉(zhuǎn)移not_yet

:

subsi,typebranch_tableloopLcontinue:……routine1:……routine2:…………調(diào)試源程序基址變址尋址cmpal,0調(diào)試源程序34習(xí)題5.21 試寫一程序,要求比較數(shù)組ARRAY中的三個16位補(bǔ)碼數(shù),并根據(jù)比較結(jié)果在終端上顯示如下信息:(1)如果三個數(shù)都不相等,則顯示0 (2)如果有兩個相等則顯示1(3)如果都相等,則顯示2dsegsegment arraydw3dup(?)dsegendscsegsegment…… movcx,3 leasi,arraybegin: pushcx movcl,4 movdi,4 movdl,’‘ movah,02 int21hinput: movah,01h int21h andal,0fh shldx,cl ordl,al decdi jneinput mov[si],dx addsi,2 popcx loopbegin習(xí)題5.21 試寫一程序,要求比較數(shù)組ARRAY中的三個135compa:leasi,array movdx,0 movax,[si] movbx,[si+2] cmpax,bx jnenext1 incdxnext1: cmp[si+4],ax jnenext2 incdxnext2: cmp[si+4],bx jnenum incdxnum: cmpdx,3 jldisp decdxdisp: movah,2 adddl,30h int21hmainendpcsegends endstartcompa:leasi,arraynum: cmp36習(xí)題5.23 已定義整型變量A、B(1)若只有一個奇數(shù),奇數(shù)存入A,偶數(shù)存入B(2)若兩個奇數(shù),A=A+1B=B+1(3)若兩個偶數(shù),A、B值不變begin: movax,a movbx,b xorax,bx testax,1h jzclass;同奇同偶,轉(zhuǎn)移 textbx,1h jzexit xchgbx,a movb,bx jmpexitclass: testbx,1h jzexit;若同偶,退出 incb incaexit: ret習(xí)題5.23 已定義整型變量A、Bbegin: mova375.3如何在實(shí)模式下發(fā)揮80386及其后繼機(jī)型的優(yōu)勢80386及其后繼機(jī)型不但兼容8086的程序,運(yùn)行速度更快;而且還有其它的一些優(yōu)勢:5.3.1充分利用高檔機(jī)的32位字長特征5.3.2通用寄存器可作為指針寄存器5.3.3與比例因子有關(guān)的尋址方式調(diào)試源程序例5.115.3如何在實(shí)模式下發(fā)揮80386及其后繼機(jī)型的優(yōu)勢5.38通用寄存器作指針寄存器8個32位通用寄存器都可以作為基址或變址寄存器使用,但注意它們的高16位應(yīng)為0。32位字長特征計算機(jī)一次能夠處理32位的數(shù)據(jù),可以訪問32位的8個通用寄存器,但EIP和EFLAGS在實(shí)模式下只有低16位可以使用。比例因子方便了表格處理和多位數(shù)組處理實(shí)模式段的大小限于64K通用寄存器作指針寄存器32位字長特征比例因子實(shí)模式段的大小限39實(shí)模式下的程序是一種混合的16位和32位代碼純16位模塊(1)所有段長都小于64KB;(2)數(shù)據(jù)項主要是8位或16位的(3)指向代碼或數(shù)據(jù)的指針只有16位偏移地址(4)只有16位段之間傳送控制純32模塊(1)段長可大于64KB(0-4GB);(2)數(shù)據(jù)項主要是8位或32位的(3)指向代碼或數(shù)據(jù)的指針有32位偏移地址(4)只有32位段之間傳送控制8086/80286實(shí)模式80386+保護(hù)模式實(shí)模式下的程序是一種混合的16位和32位代碼純16位模塊純340386+實(shí)模式下的程序在同一模塊中,允許同時使用16位和32位的操作數(shù)和尋址方式段必須實(shí)16位的,但段中的指令可以是混合的16位和32位代碼奔騰4386+實(shí)模式下的程序奔騰441第五章作業(yè) Page193~1955.105.21

第五章作業(yè)42第五章循環(huán)與分支程序設(shè)計5.1循環(huán)程序設(shè)計5.2分支程序設(shè)計5.3如何在實(shí)模式下發(fā)揮80386及其后繼機(jī)型的優(yōu)勢第五章循環(huán)與分支程序設(shè)計5.1循環(huán)程序設(shè)計43

1.編寫匯編語言程序步驟l

分析實(shí)際問題,確定解決問題的算法l

按算法畫出程序流程圖l

按流程圖編寫程序l上機(jī)調(diào)試,運(yùn)行程序注:本教材所討論的編程環(huán)境只限于在DOS操作系統(tǒng)下的實(shí)模式

1.編寫匯編語言程序步驟注:本教材所討論的編程環(huán)境只限于442.判斷程序質(zhì)量的標(biāo)準(zhǔn)程序的正確性程序的可讀性程序的執(zhí)行時間程序所占內(nèi)存大小2.判斷程序質(zhì)量的標(biāo)準(zhǔn)453.幾種程序結(jié)構(gòu)順序結(jié)構(gòu)循環(huán)結(jié)構(gòu)分支結(jié)構(gòu)子程序結(jié)構(gòu)3.幾種程序結(jié)構(gòu)46順序結(jié)構(gòu)形式順序結(jié)構(gòu)形式47循環(huán)結(jié)構(gòu)形式當(dāng)型循環(huán)(當(dāng)條件成立進(jìn)入循環(huán))循環(huán)初始設(shè)置循環(huán)體循環(huán)條件判斷?YN直到型循環(huán)(直到條件成立退出循環(huán))YN循環(huán)初始設(shè)置循環(huán)體循環(huán)條件判斷?循環(huán)結(jié)構(gòu)形式當(dāng)型循環(huán)循環(huán)初始設(shè)置循環(huán)體循環(huán)條件判斷?YN直到48兩個分支YN

、、、CMPAL,BLJGgreat

JMPexitgreat:

exit:、、、、、、

AL≤BL處理AL>BL處理分支結(jié)構(gòu)形式兩個分支YN、、、AL≤BL處理AL>BL處49三個分支

、、、CMPAL,0

JGgreat

JLless

JMPexitless:

JMPexitgreat:

exit:、、、AL=0處理AL>0處理AL<0處理YYNN分支結(jié)構(gòu)形式……三個分支、、、AL=0處理AL>0處理AL501.多處調(diào)用完成同一功能的子程:codeSEGMENTstart:、、

CALLsubp、、

CALLsubp、、

CALLsubp、、MOVAH,4CHINT21HsubpPROC、、、、RETsubpENDPcodeENDSENDstart2.模塊化程序設(shè)計:codeSEGMENTbegin:CALL

sub1

CALLsub2

CALLsub3MOVAH,4CHINT21Hsub1PROC、、RETsub1ENDPsub2PROC、、RETsub2ENDPsub3PROC、、RETsub3ENDPcodeENDSENDbegin

子程結(jié)構(gòu)形式注意返回DOS語句位置1.多處調(diào)用完成同一功能的子程:2.模塊化程序設(shè)計:子程結(jié)構(gòu)51開

始結(jié)

化循環(huán)的初始狀態(tài)

環(huán)

體循環(huán)的工作部分及修改部分

控制條件

計數(shù)控制特征值控制地址邊界控制5.1.1循環(huán)程序的結(jié)構(gòu)形式5.1循環(huán)程序設(shè)計(1)DO-WHILE結(jié)構(gòu)(2)DO-UNTIL結(jié)構(gòu)開始結(jié)束初始化52有關(guān)字符、數(shù)碼轉(zhuǎn)換的處理1.計算機(jī)處理字符時,常用的字符編碼是ASCII碼。2.數(shù)字和字母的ASCII碼是一個有序序列數(shù)字0~9:30H~39H大寫字母A~Z:41H~5AH小寫字母a~z:61H~7AH5.1.2循環(huán)程序設(shè)計方法例5.1將寄存器BX中的內(nèi)容以十六進(jìn)制形式顯示出來。 有關(guān)字符、數(shù)碼轉(zhuǎn)換的處理5.1.2循環(huán)程序設(shè)計方法例5.53BX是一個16位寄存器二進(jìn)制1010100100111110

用十六進(jìn)顯示時,每4位用一個字符顯示,共4個其中:0000→’0’30H,1010→’A’41H

0001→’1’31H,1011→’B’42H、、、、

1001→’9’39H,1111→’F’46H?十六進(jìn)制A93E屏幕上的顯示‘A’‘9’‘3’‘E’對應(yīng)的ASCII41H39H33H45HBX是一個16位寄存器用十六進(jìn)顯示時,每4位用一個字符顯54BX1234BX155算法:取出要顯示的某4位,轉(zhuǎn)換為對應(yīng)的ASCII碼,再調(diào)用DOS系統(tǒng)功能進(jìn)行顯示。(1)對于0000~1001(0~9),先擴(kuò)展成一個字節(jié),高4位清0,加上30H后,即可得字符’0’~’9’對應(yīng)的ASCII碼。00000001B+30H=31H00001001B+30H=39H

0001B‘1’1001B‘9’(2)對于1010~1111(A~F),先擴(kuò)展成一個字節(jié),高4位清0,

加上30H后,還要再加上07H,才能得到’A’~’F’對應(yīng)的ASCII碼00001010B+30H+07H=41H00001111B+30H+07H=46H

1010B‘A’1111B‘F’算法:(1)對于0000~1001(0~9),先擴(kuò)展56codeSEGMENTASSUMECS:codestart:MOVCH,4;字符個數(shù)rotate:MOVCL,4;循環(huán)移位次數(shù)

ROLBX,CL

;取顯示位的值

MOVAL,BL

;保存在AL中

ANDAL,0FH

;清除高4位

ADDAL,30H

;轉(zhuǎn)變?yōu)閿?shù)字的ASCII

CMPAL,3aH;大于3aH,則應(yīng)轉(zhuǎn)變

JLprint;為數(shù)字0~9的ASCII

ADDAL,07H;為字母A~F的ASCIIprint:MOVDL,AL;送

ASCII字符到DLMOVAH,2;顯示DL中的字符INT21HDECCH;顯示結(jié)束?

JNZnextMOVAH,4CH;返回DOSINT21HcodeENDS

ENDstart顯示字符個數(shù)CH=4循環(huán)移位次數(shù)CL=4BX循環(huán)左移4位,將要顯示的值移至低4位,保存在AL中清AL的高4位,只保留要顯示位的值A(chǔ)L←AL+30H完成數(shù)值0~9的ASCII碼轉(zhuǎn)換YNAL←AL+07H完成數(shù)值A(chǔ)~F的ASCII碼轉(zhuǎn)換用02功能顯示DL中的字符YN返回DOSAL超出39H?CH←CH-1轉(zhuǎn)換結(jié)束?開始codeSEGMENT顯示字符個數(shù)CH=4BX循環(huán)左57例5.2在ADDR單元中存放著數(shù)Y,度編制一程序把Y中1的個數(shù)存入COUNT單元中。datareasegment addredw1234h countdw?datareaends movcx,0 movbx,addre movax,bxagain: testax,0ffffh jzexit jnsshift inccxshift: shlax,1 jmpagainexit: movcount,cx ret 例5.2在ADDR單元中存放著數(shù)Y,度編制一程序把Y中158例5.4

將正數(shù)n插入一個已整序的字?jǐn)?shù)組的正確位置。

xdw?array_headdw3,5,15,23,37,49,52,65,78,99array_enddw105ndw32movax,nmovarray_head-2,0ffffhmovsi,0compare:cmparray_end[si],axjleinsertmovbx,array_end[si]movarray_end[si+2],bxsubsi,2jmpshortcompareinsert:movarray_end[si+2],ax

-1

3

5

49

15

52

23

37

105

99

78

65

32xn例5.4將正數(shù)n插入一個已整序的字?jǐn)?shù)組的正確位置。59例5.5Zi=Xi+Yi

LOGIC_RULE DW 00DCH …… MOV BX,0 MOV CX,10 MOV DX,LOGIC_RULENEXT: MOV AX,X[BX]

SHR DX,1

JC SUBTRACT ADD AX,Y[BX] JMP SHORTRESULTSUBTRACT: SUB AX,Y[BX]RESULT: MOV Z[BX],AX ADD BX,2 LOOP NEXT RET ……例5.5Zi=Xi+Yi LOGIC_RULE DW 60例5.6鍵入一行以空格開頭以空格結(jié)束的字符串datareasegment buffer db80dup(?) flag db?datareaends leabx,buffer movflag,0next: movah,01;讀鍵盤 int21h;所讀內(nèi)容放入al testflag,01h;flag=1? jnzfollow;flag=0,zf=1不轉(zhuǎn) cmpal,20h;al是空格? jnzexit;不是,zf=0退出 movflag,1;置標(biāo)志flag=1 jmpnextfollow: cmpal,20h;al是空格? jzexit;是,zf=1,退出 mov[bx],al;不是,保存 incbx;數(shù)組索引加1 jmpnextexit:20abcdef20flag=01jzexit成立例5.6鍵入一行以空格開頭以空格結(jié)束的字符串datare615.1.3多重循環(huán)程序設(shè)計基本方法與單重循環(huán)相同,但要注意:1、分別考慮各重循環(huán)的控制條件及其程序?qū)崿F(xiàn),相互之間不能混淆2、每次從外層循環(huán)再次進(jìn)入內(nèi)層循環(huán)時,初始條件要重新設(shè)置5.1.3多重循環(huán)程序設(shè)計基本方法與單重循環(huán)相同,但要注意62例5.7

將首地址為a的字?jǐn)?shù)組從大到小排序(氣泡算法,多重循環(huán))

adw100,30,78,99,15,-1,66,54,189,256movcx,10;待排序數(shù)的個數(shù)deccx;外循環(huán)的次數(shù)loop1:movdi,cx;暫存外循環(huán)次數(shù)movbx,0;數(shù)組下標(biāo)loop2:movax,a[bx];取第bx個數(shù)cmpax,a[bx+2];與后一個數(shù)比較jgecontinue;[bx]>=[bx+2]xchgax,a[bx+2];<,則交換位置mova[bx],axcontinue:addbx,2;指向下一個數(shù)looploop2

movcx,di;恢復(fù)外循環(huán)次數(shù)looploop1例5.7將首地址為a的字?jǐn)?shù)組從大到小排序(氣泡算法,多重循63例5.8附加段字?jǐn)?shù)組首地址存于DI,第1字存放長度,從小到大排序

extrasegment

adw10,10h,12h,32h,21h,11h,56h,43h,33h,3h,67h

extraendsdatasegment start_addrdw? save_cntdw?dataends leadi,a;取有效地址 movstart_addr,di movcx,es:[di];取長度 movsave_cnt,cx;數(shù)組長度init: movbx,1;結(jié)束標(biāo)志 decsave_cnt jzsorted;zf=1,轉(zhuǎn)移 movcx,save_cnt movdi,start_addrnext: adddi,2 movax,es:[di];取數(shù) cmpes:[di+2],ax;比較 jaecont;>=,轉(zhuǎn)移,不換 xchges:[di+2],ax moves:[di],ax subbx,bx;排序標(biāo)志cont: loopnext cmpbx,0;bx=1,已排好 jeinitsorted: movdi,start_addr例5.8附加段字?jǐn)?shù)組首地址存于DI,第1字存放長度,從小到64練習(xí)5.11:從鍵盤輸入一系列以$結(jié)束的字符串,統(tǒng)計數(shù)字字符的個數(shù)datasegment countdw0 buffdb50dup(?)dataendsprognamsegmentmainprocfar assumecs:prognamstart: pushds subax,ax pushax movax,data movds,ax leabx,buff;取緩沖地址input: movah,01;從鍵盤讀串 int21H;存入al中 mov[bx],al;保存字符 incbx;buff數(shù)組下標(biāo) cmpal,‘$‘;是不是$ jnzinput;是,結(jié)束讀 leabx,buff;取串地址 movax,0next: movcl,[bx];取串中字符 incbx;指向下一字符 cmpcl,‘$’;是不是$ jzdisp;是,zf=1,轉(zhuǎn)移 cmpcl,30h;與’0’比較 jbcont;<‘0’,不計數(shù) cmpcl,39h;與’9’比較 jnbenext;>’9’,不計數(shù) incax;計數(shù)cont: jmpnextdisp: ret mainendpprognamends endstart練習(xí)5.11:從鍵盤輸入一系列以$結(jié)束的字符串,統(tǒng)計數(shù)字字符65練習(xí)5.11:測試一字符串是否存在數(shù)字,若存在,置CL第5位置1,否則置0datasegmentstringdb'abcqdefghijklmnopqrs'dataendsprognam segmentmainprocfarassumecs:prognam,ds:data,es:datastart:pushdssubax,axpushaxmovax,datamovds,axmoves,axbegin: movcx,20;字符個數(shù) movsi,0;數(shù)組下標(biāo)again: moval,string[si] cmpal,30h;與’0’比較 jbgoon;<,轉(zhuǎn)移 cmpal,39h;與‘9’比較 jagoon;>,轉(zhuǎn)移 orcl,20h;有數(shù)字,置5位 jmpexitgoon: incsi;數(shù)組下標(biāo)加1 loopagain andcl,0dfh;無數(shù)字,清5位exit: ret mainendpprognamends endstart練習(xí)5.11:測試一字符串是否存在數(shù)字,若存在,置CL第5位66循環(huán)程序設(shè)計小結(jié)1、循環(huán)控制條件的選擇: a.循環(huán)次數(shù)已知,采用LOOP b.循環(huán)次數(shù)已知,但有可能使用其他特征或條件結(jié)束循環(huán), 可采用LOOPZ和LOOPNZ c.循環(huán)次數(shù)未知,具體問題具體分析2、設(shè)立條件標(biāo)志位的方法循環(huán)程序設(shè)計小結(jié)675.2分支程序設(shè)計5.2.1分支程序的結(jié)構(gòu)形式雙分支與多分支的共同特點(diǎn):運(yùn)行方向是向前的在某一種特定條件下,只能執(zhí)行其中的一個分支5.2.1分支程序設(shè)計方法1、使用CMP、TEST等運(yùn)算型指令+條件轉(zhuǎn)移指令2、使用邏輯尺的方法3、使用跳躍表法實(shí)現(xiàn)CASE結(jié)構(gòu)5.2分支程序設(shè)計5.2.1分支程序的結(jié)構(gòu)形式雙分支與68例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1dsegsegmentlow_idxdw ?high_idxdw ?listdw12,11,22,33,44,55,66,77,88,99,111,222,333targetdw 77dsegendscsegsegmentmainprocfar assumecs:cseg,ds:dseg,es:dsegstart: pushds subax,ax pushax movax,dseg movds,ax moves,ax例5.9折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長69例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1 movax,target ; leadi,list;取數(shù)組首地址 cmpax,es:[di+2];取第1個數(shù) jachk_last ;>第1個,檢查最后1個 leasi,es:[di+2];<=第1個 jeexit ;=,退出 stc ;CF=1,沒找到 jmpexitchk_last:movsi,es:[di] ;下面三條使SI指向

shlsi,1 ;數(shù)組末元素

addsi,di cmpax,es:[si] ;與末元素比較 jbsearch ;<,搜索數(shù)組 jeexit ;=,退出 stc ;CF=1,沒找到 jmpexit0400list100102104106108例5.9折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長70例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1search: movlow_idx,1 ;搜索開始的地方 movbx,es:[di] ;數(shù)組長度 movhigh_idx,bx ;搜索結(jié)束的地方 movbx,di ;list地址mid: movcx,low_idx ; movdx,high_idx ;

cmpcx,dx ;比較’頭’與’末’指針 jano_match ;>,’頭’到’末’之后 addcx,dx ;以下三條計算 shrcx,1 ;’頭’與’末’的中點(diǎn) movsi,cx

shlsi,1 ;對準(zhǔn)中間’字’0500100102104106108list10A(1+5)/2=33*2=6DI偏移6,即106,即第3字例5.9折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長71compare: cmpax,es:[bx+si] ;比較,bx指向數(shù)組首元素 jeexit ;=,找到,退出 jahighter ;>,調(diào)節(jié)搜索’頭’ deccx ;<= movhigh_idx,cx ;調(diào)節(jié)搜索’末’ jmpmidhighter: inccx movlow_idx,cx ;調(diào)節(jié)搜索’頭’ jmpmidno_match: stcexit: ret例5.9

折半查找:附加段有一個有序字?jǐn)?shù)組,首字表示數(shù)組長度,AX是待查字,若找到CF=0,否則CF=1compare:例5.9折半查找:附加段有一個有序字?jǐn)?shù)組72例5.10

根據(jù)AL寄存器中哪一位為1(從低位到高位)把程序轉(zhuǎn)移到8個不同的程序分支去。branch_tabledwroutine1

dwroutine2

dwroutine3

dwroutine4

dwroutine5

dwroutine6

dwroutine7

dwroutine8注意:DW標(biāo)號的使用例5.10根據(jù)AL寄存器中哪一位為1(從低位到高位)把程73寄存器間接尋址cmpal,0jecontinueleabx,branch_tableL

:shral,1

溫馨提示

  • 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

提交評論