微機(jī)接口與原理5_第1頁
微機(jī)接口與原理5_第2頁
微機(jī)接口與原理5_第3頁
微機(jī)接口與原理5_第4頁
微機(jī)接口與原理5_第5頁
已閱讀5頁,還剩97頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

匯編語言程序設(shè)計(jì)

簡(jiǎn)明教程1第四章選擇和循環(huán)

4.1測(cè)試和控制指令

4.2選擇結(jié)構(gòu)程序

4.3循環(huán)結(jié)構(gòu)程序

4.4程序的調(diào)試 習(xí)題四2按照指令執(zhí)行的順序,程序的結(jié)構(gòu)可以劃分成以下三種。

順序結(jié)構(gòu):程序按照它編寫的順序執(zhí)行,每條指令只執(zhí)行一

次,這樣的程序稱為“順序結(jié)構(gòu)”的程序。

循環(huán)結(jié)構(gòu):一組指令被反復(fù)地執(zhí)行,這樣的程序稱為“循環(huán)結(jié)

構(gòu)”或者“重復(fù)結(jié)構(gòu)”的程序。

選擇結(jié)構(gòu):根據(jù)某個(gè)條件,一部分指令被執(zhí)行,另一部分指

令沒有被執(zhí)行,這樣的程序稱為“選擇結(jié)構(gòu)”或者

“分支結(jié)構(gòu)”的程序。一個(gè)實(shí)際運(yùn)行的程序,常常是由以上三種結(jié)構(gòu)的程序組合而成的,上面的三種結(jié)構(gòu)稱為程序的“基本結(jié)構(gòu)”。使用這三種基本結(jié)構(gòu),可以編寫出任何所需要的程序。程序結(jié)構(gòu)3

4.1測(cè)試和轉(zhuǎn)移控制指令4.1.1無條件轉(zhuǎn)移指令4.1.2比較和測(cè)試指令4.1.3條件轉(zhuǎn)移指令4執(zhí)行JMP指令后,程序轉(zhuǎn)移到新的“目的位置”執(zhí)行。1.無條件轉(zhuǎn)移指令無條件轉(zhuǎn)移指令的一般格式:JMP 目的位置5CODE SEGMENT ASSUME CS:CODESTART: MOV DL,20HONE: MOV AH,2 INT 21H ;輸出DL中的字符

INC DL ;修改DL中的字符代碼

JMP ONE ;轉(zhuǎn)移到“ONE”處繼續(xù)執(zhí)行

MOV AX,4C00H INT 21HCODE ENDS END START[例4-1]用JMP指令實(shí)現(xiàn)轉(zhuǎn)移64.1.1無條件轉(zhuǎn)移指令只要執(zhí)行無條件轉(zhuǎn)移指令JMP,就使程序轉(zhuǎn)到指定的目標(biāo)地址處,從目標(biāo)地址處開始執(zhí)行那里的指令操作數(shù)label是要轉(zhuǎn)移到的目標(biāo)地址(目的地址、轉(zhuǎn)移地址)JMP指令分成4種類型:⑴段內(nèi)轉(zhuǎn)移、直接尋址⑵段內(nèi)轉(zhuǎn)移、間接尋址⑶段間轉(zhuǎn)移、直接尋址⑷段間轉(zhuǎn)移、間接尋址JMPlabel

;程序轉(zhuǎn)向label標(biāo)號(hào)指定的地址JMP7目標(biāo)地址的尋址方式直接尋址方式轉(zhuǎn)移地址象立即數(shù)一樣,直接在指令的機(jī)器代碼中,就是直接尋址方式間接尋址方式轉(zhuǎn)移地址在寄存器或主存單元中,就是通過寄存器或存儲(chǔ)器的間接尋址方式用標(biāo)號(hào)表達(dá)用寄存器或存儲(chǔ)器操作數(shù)表達(dá)JMP8目標(biāo)地址的范圍:段內(nèi)(近程)段內(nèi)轉(zhuǎn)移——短轉(zhuǎn)移(short)轉(zhuǎn)移范圍可以用一個(gè)字節(jié)表達(dá),在段內(nèi)-128~+127范圍的轉(zhuǎn)移段內(nèi)轉(zhuǎn)移——近轉(zhuǎn)移(near)在當(dāng)前代碼段64KB范圍內(nèi)轉(zhuǎn)移(±32KB范圍)不需要更改CS段地址,只要改變IP偏移地址代碼段代碼段JMP9目標(biāo)地址的范圍:段間(遠(yuǎn)程)段間轉(zhuǎn)移——遠(yuǎn)轉(zhuǎn)移(far)從當(dāng)前代碼段跳轉(zhuǎn)到另一個(gè)代碼段,可以在1MB范圍需要更改CS段地址和IP偏移地址目標(biāo)地址必須用一個(gè)32位數(shù)表達(dá),叫做32位遠(yuǎn)指針,它就是邏輯地址代碼段代碼段

實(shí)際編程時(shí),匯編程序會(huì)根據(jù)目標(biāo)地址的距離,自動(dòng)處理成短轉(zhuǎn)移、近轉(zhuǎn)移或遠(yuǎn)轉(zhuǎn)移程序員可用操作符short、nearptr

或farptr

強(qiáng)制JMP10JMP段內(nèi)轉(zhuǎn)移、直接尋址JMPlabel

;IP←IP+位移量位移量是緊接著JMP指令后的那條指令的偏移地址到目標(biāo)指令的偏移地址的地址位移當(dāng)向地址增大方向轉(zhuǎn)移時(shí),位移量為正;向地址減小方向轉(zhuǎn)移時(shí),位移量為負(fù)

jmp

again

;轉(zhuǎn)移到again處繼續(xù)執(zhí)行

……again:

dec

cx

;標(biāo)號(hào)again的指令

……

jmp

output

;轉(zhuǎn)向output

……output:

movresult,al

;標(biāo)號(hào)output的指令實(shí)際為相對(duì)尋址11段內(nèi)轉(zhuǎn)移、間接尋址JMPr16/m16 ;IP←r16/m16將一個(gè)16位寄存器或主存字單元內(nèi)容送入IP寄存器,作為新的指令指針,但不修改CS寄存器的內(nèi)容jmpax ;IP←AXjmpwordptr[2000h]

;IP←[2000h]

JMPJMP121)JMPONE ;近程直接轉(zhuǎn)移2)LEADX,ONEJMPDX ;寄存器間接段內(nèi)轉(zhuǎn)移3)LEABX,TARGETJMPWORDPTR[BX] ;存儲(chǔ)器間接段內(nèi)轉(zhuǎn)移4)JMPTARGET ;存儲(chǔ)器間接段內(nèi)轉(zhuǎn)移已在數(shù)據(jù)段定義存儲(chǔ)器單元“TARGET”:

TAEGET DWONE下面四組指令都可以實(shí)現(xiàn)向標(biāo)號(hào)“ONE”的轉(zhuǎn)移:13段間轉(zhuǎn)移、直接尋址JMPfarptrlabel

;IP←label的偏移地址 ;CS←label的段地址將標(biāo)號(hào)所在段的段地址作為新的CS值,標(biāo)號(hào)在該段內(nèi)的偏移地址作為新的IP值;這樣,程序跳轉(zhuǎn)到新的代碼段執(zhí)行jmpfarptr

otherseg

;遠(yuǎn)轉(zhuǎn)移到代碼段2的othersegJMP14段間轉(zhuǎn)移、間接尋址JMPfarptr

mem

;IP←[mem],CS←[mem+2]用一個(gè)雙字存儲(chǔ)單元表示要跳轉(zhuǎn)的目標(biāo)地址。這個(gè)目標(biāo)地址存放在主存中連續(xù)的兩個(gè)字單元中的,低位字送IP寄存器,高位字送CS寄存器movwordptr[bx],0movwordptr[bx+2],1500hJMPfarptr[bx];轉(zhuǎn)移到1500h:0JMP151)JMPFARPTRTWO ;遠(yuǎn)程直接轉(zhuǎn)移2)LEABX,FAR_TGTJMPDWORDPTR[BX] ;遠(yuǎn)程間接轉(zhuǎn)移3)JMPFAR_TGT ;遠(yuǎn)程間接轉(zhuǎn)移假設(shè)已在數(shù)據(jù)段定義存儲(chǔ)器單元“FAR_TGT”如下:

FAR_TGT DD TWO下面三組指令都可以實(shí)現(xiàn)向遠(yuǎn)程標(biāo)號(hào)“TWO”的轉(zhuǎn)移:164.1.2比較和測(cè)試指令(1)CMP(Compare,比較)指令指令格式:

CMP 目的操作數(shù),源操作數(shù)目的操作數(shù):8位/16位/32位的寄存器/存儲(chǔ)器操作數(shù)。源操作數(shù):與目的操作數(shù)同類型的寄存器/存儲(chǔ)器/立即數(shù)。功能:目的操作數(shù)-源操作數(shù),保留運(yùn)算產(chǎn)生的標(biāo)志位,不保留運(yùn)算的差。用來比較兩個(gè)有符號(hào)數(shù)或無符號(hào)數(shù)的大小。

17假設(shè)(CX)=0A0B0H,指令“CMPCX,0”執(zhí)行后:

ZF=0(CX)≠0OF=0減法操作沒有產(chǎn)生溢出(SF是正確的結(jié)果符號(hào)位)

SF=1如果CX中存放的是有符號(hào)數(shù),這個(gè)數(shù)是負(fù)數(shù)

CF=0如果CX中存放的是無符號(hào)數(shù),這個(gè)數(shù)大于018CF=0,目的操作數(shù)≥源操作數(shù)CF=1,目的操作數(shù)<源操作數(shù)對(duì)于有符號(hào)數(shù):OF=0時(shí),SF為正確的結(jié)果符號(hào)

OF=1時(shí),SF與正確的符號(hào)位相反

OF⊕SF的運(yùn)算結(jié)果反映了正確的結(jié)果符號(hào)OF⊕SF=0,目的操作數(shù)≥源操作數(shù)OF⊕SF=1,目的操作數(shù)<源操作數(shù)對(duì)于無符號(hào)數(shù):19ZF=0 (X)≠5OF=1

減法操作產(chǎn)生溢出,SF是錯(cuò)誤的結(jié)果符號(hào)位SF=0

OF⊕SF=1,目的操作數(shù)<源操作數(shù) 如果X中存放的是有符號(hào)數(shù),X<5CF=0 如果X中存放的是無符號(hào)數(shù),X>5

(由于ZF=0,所以不相等)例:假設(shè)存儲(chǔ)器變量(X)=80H,指令“CMPX,5”執(zhí)行后:20指令格式:

TEST 目的操作數(shù),源操作數(shù)目的操作數(shù):8位/16位/32位的寄存器/存儲(chǔ)器操作數(shù)。源操作數(shù):與目的操作數(shù)同類型的寄存器/存儲(chǔ)器/立即數(shù)。功能:TEST指令將目的操作數(shù)與源操作數(shù)進(jìn)行邏輯乘運(yùn)算,保留運(yùn)算產(chǎn)生的各標(biāo)志位,但是不保留邏輯乘的結(jié)果。該

指令用來測(cè)試目的操作數(shù)中某幾位二進(jìn)制的特征。(2)TEST(Test,測(cè)試)指令21如果ZF=0,說明BL寄存器的D2D1≠00,這兩位為01,10或11。如果ZF=1,說明BL寄存器的D2D1=00,這兩位為00。指令TEST VAR,1執(zhí)行后:如果ZF=0,說明變量VAR的D0位為1,該數(shù)為奇數(shù)如果ZF=1,說明變量VAR的D0位為0,該數(shù)為偶數(shù)指令TEST BL,6執(zhí)行后:224.1.3條件轉(zhuǎn)移指令“J”是條件轉(zhuǎn)移指令操作碼的第一個(gè)字母“cc”是代表轉(zhuǎn)移條件的1~3個(gè)字母“l(fā)abel”是轉(zhuǎn)移目的地的標(biāo)號(hào)。對(duì)于16位80X86CPU,條件轉(zhuǎn)移指令的轉(zhuǎn)移范圍在下一條指令地址-128~+127字節(jié)之間。條件轉(zhuǎn)移指令格式:

Jcc label23兩個(gè)有符號(hào)數(shù)的比較結(jié)果通過OF,SF,ZF反映出來

G(Greater,大于)L(Less,小于)E(Equal,等于)N(Not,否)例:JG/JNLE 大于(不小于等于)則轉(zhuǎn)移

JNL/JGE不小于(大于或等于)則轉(zhuǎn)移

JE/JZ 等于(為零)則轉(zhuǎn)移(1)有符號(hào)數(shù)比較的條件轉(zhuǎn)移指令24指令助記符

指令功能轉(zhuǎn)移條件JG,JNLE大于(不小于等于)時(shí)轉(zhuǎn)移OF⊕SF=0且ZF=0JGE,JNL大于等于(不小于)時(shí)轉(zhuǎn)移OF⊕SF=0JZ,JE為零(相等)時(shí)轉(zhuǎn)移ZF=1JNZ,JNE不為零(不相等)時(shí)轉(zhuǎn)移ZF=0JL,JNGE小于(不大于等于)時(shí)轉(zhuǎn)移OF⊕SF=1JLE,JNG小于等于(不大于)時(shí)轉(zhuǎn)移OF⊕SF=1或ZF=1根據(jù)有符號(hào)數(shù)大小的條件轉(zhuǎn)移指令25MOV AX,X ;取出X的值送AXCMP AX,Y ;比較兩個(gè)操作數(shù),建立需要的標(biāo)志位JG GREATER

;如果X>Y,轉(zhuǎn)移到“GREATER”處執(zhí)行JE EQUAL

;如果X=Y,轉(zhuǎn)移到“EQUAL”處執(zhí)行LESS: ;否則,執(zhí)行標(biāo)號(hào)“LESS”處的指令

……

jmp finishGREATER: ……

jmp finishEQUAL: ……finish:根據(jù)有符號(hào)字變量X和Y的大小的程序分支26

SUB AX,BX ;AX←(AX)-(BX),建立標(biāo)志位

JGE SKIP ;如果(AX)≥0,轉(zhuǎn)標(biāo)號(hào)“SKIP” NEG AX ;如果(AX)<0,把AX的值取反SKIP:

JGGREATER ;如果X>Y,轉(zhuǎn)移到“GREATER”處

JEEQUAL ;如果X=Y,轉(zhuǎn)移到“EQUAL”處

JLLESS ;如果X<Y,轉(zhuǎn)移到“LESS”處LESS: ……下面程序能夠正確運(yùn)行,但最后一條指令有“畫蛇添足”之嫌。下面的程序計(jì)算AX=|AX-BX|27例18:比較有符號(hào)數(shù)

cmp

ax,bx

;比較ax和bx

jnlnext

;若ax≥bx,轉(zhuǎn)移

xchg

ax,bx

;若ax<bx,交換next: ...結(jié)果:AX保存較大的有符號(hào)數(shù)28求N個(gè)數(shù)的最大值求N個(gè)數(shù)據(jù)中最大值的方法:

預(yù)設(shè)一個(gè)“最大值”,

取出一個(gè)數(shù)據(jù)與這個(gè)“最大值”進(jìn)行比較,如果數(shù)據(jù)大于“最大值”,則將該數(shù)據(jù)作為新的“最大值”。

進(jìn)行N次比較之后留下的就是這N個(gè)數(shù)據(jù)的最大值。預(yù)設(shè)的“最大值”的初值可以從N個(gè)數(shù)據(jù)中任取一個(gè),也可以根據(jù)數(shù)據(jù)的范圍,取一個(gè)該范圍內(nèi)的最小的數(shù)。29例:求5個(gè)帶符號(hào)數(shù)的最大值

MOVCX,4 LEA BX,NUM MOVAL,[BX]NEXT:INC BX

CMPAL,[BX]

JGNEXT1

MOVAL,[BX]NEXT1:LOOPNEXT30 兩個(gè)有符號(hào)數(shù)的比較結(jié)果通過CF,ZF反映出來,代表轉(zhuǎn)移條件的字母:

A(Above,高于)

B(Below,低于)

E(Equal,等于)(2)無符號(hào)數(shù)比較的條件轉(zhuǎn)移指令31指令助記符指令功能轉(zhuǎn)移條件JA,JNBE高于(不低于等于)時(shí)轉(zhuǎn)移CF=0且ZF=0JAE,JNB,JNC高于等于(不低于)時(shí)轉(zhuǎn)移CF=0JZ,JE為零(相等)時(shí)轉(zhuǎn)移ZF=1JNZ,JNE不為零(不相等)時(shí)轉(zhuǎn)移ZF=0JB,JNAE,JC低于(不高于等于)時(shí)轉(zhuǎn)移CF=1JBE,JNA低于等于(不高于)時(shí)轉(zhuǎn)移CF=1或ZF=1根據(jù)無符號(hào)數(shù)大小的條件轉(zhuǎn)移指令32(3)根據(jù)單個(gè)標(biāo)志位的條件轉(zhuǎn)移指令這組指令單獨(dú)判斷5個(gè)狀態(tài)標(biāo)志之一⑴JZ/JE和JNZ/JNE:利用零標(biāo)志ZF,判斷結(jié)果是否為零(或相等)⑵JS和JNS:利用符號(hào)標(biāo)志SF,判斷結(jié)果是正是負(fù)⑶JO和JNO:利用溢出標(biāo)志OF,判斷結(jié)果是否產(chǎn)生溢出⑷JP/JPE和JNP/JPO:利用奇偶標(biāo)志PF,判斷結(jié)果中“1”的個(gè)數(shù)是偶是奇⑸JC/JB/JNAE和JNC/JNB/JAE:利用進(jìn)位標(biāo)志CF,判斷結(jié)果是否進(jìn)位或借位Jcc例題12例題13例題14例題15例題1633例12:JZ/JNZ指令

testal,80h ;測(cè)試最高位

jznext0

;D7=0(ZF=1),轉(zhuǎn)移

movah,0ffh ;D7=1,順序執(zhí)行

jmpdone

;無條件轉(zhuǎn)向next0:

movah,0done: ... testal,80h ;測(cè)試最高位

jnznext1

;D7=1(ZF=0),轉(zhuǎn)移

movah,0 ;D7=0,順序執(zhí)行

jmpdone

;無條件轉(zhuǎn)向next1:

movah,0ffhdone: ...34例13:JS/JNS指令;計(jì)算|X-Y|(絕對(duì)值);X和Y為存放于X單元和Y單元的16位操作數(shù);結(jié)果存入result

movax,X subax,Y

jns

nonneg

negax ;neg是求補(bǔ)指令nonneg:

movresult,ax35例14:JO/JNO指令;計(jì)算X-Y;;X和Y為存放于X單元和Y單元的16位操作數(shù);若溢出,則轉(zhuǎn)移到overflow處理

movax,X subax,Y

jooverflow ... ;無溢出,結(jié)果正確overflow: ... ;有溢出處理36例15:JP/JNP指令;設(shè)字符的ASCII碼在AL寄存器中;將字符加上奇校驗(yàn)位;在字符ASCII碼中為“1”的個(gè)數(shù)已為奇數(shù)時(shí);則令其最高位為“0”;否則令最高位為“1” andal,7fh

;最高位置“0”,同時(shí)判斷“1”的個(gè)數(shù)

jnpnext

;個(gè)數(shù)已為奇數(shù),則轉(zhuǎn)向next oral,80h

;否則,最高位置“1”next: ...37例16:JC/JNC指令;記錄BX中1的個(gè)數(shù)

xoral,al ;AL=0,CF=0again: testbx,0ffffh;等價(jià)于

cmpbx,0

jenext

shlbx,1

jncagain incal

jmpagainnext: ... ;AL保存1的個(gè)數(shù)另一種做法38記錄BX中“1”的個(gè)數(shù)

xoral,al ;AL=0,CF=0again: cmpbx,0

jznext

shlbx,1 ;也可使用shrbx,1

adcal,0

jmpagainnext: ... ;AL保存1的個(gè)數(shù)39 JNG Skip JMP LabelSkip: …… 對(duì)于32位80X86CPU,可以實(shí)現(xiàn)64KB范圍內(nèi)的轉(zhuǎn)移。

JG Label;如果標(biāo)號(hào)“Label”超出范圍,匯編時(shí)將出錯(cuò)可以把上面指令修改為:如果轉(zhuǎn)移地址超出范圍40指令格式:

JCXZ Label ;若CX=0,轉(zhuǎn)移到LabelJECXZ Label ;若ECX=0,轉(zhuǎn)移到Label它們的轉(zhuǎn)移范圍固定為下一條指令地址-128~+127字節(jié)以內(nèi)。(4)根據(jù)CX/ECX寄存器值的條件轉(zhuǎn)移指令414.2選擇結(jié)構(gòu)程序4.2.1基本選擇結(jié)構(gòu)4.2.2單分支選擇結(jié)構(gòu)4.2.3復(fù)合選擇結(jié)構(gòu)4.2.4多分支選擇結(jié)構(gòu)42為“|X|>3”和“|X|≤3”分別編制了進(jìn)行不同處理的指令序列。 如果條件“|X|≤3”成立(為“真”),執(zhí)行“Y=3X-5”

如果條件“|X|≤3”不成立(為“假”),執(zhí)行Y=6

通過在不同的程序之間進(jìn)行選擇,實(shí)現(xiàn)程序的不同功能,

“選擇結(jié)構(gòu)”因此得名。計(jì)算分段函數(shù)的值434.2.1基本選擇結(jié)構(gòu)44復(fù)合邏輯表達(dá)式的分解[例4-4]計(jì)算分段函數(shù)45[例4-4]計(jì)算分段函數(shù)INCLUDE YLIB.HDATA SEGMENTPROMPT DB 0DH,0AH,“InputX(-10000~+10000):$”X DW ?OUT_MSG DB 0DH,0AH,“Y=$”DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX ;裝載DS[例4-4]計(jì)算分段函數(shù)46

LEA DX,PROMPT ;輸入提示信息

CALL READINT ;從鍵盤上輸入X的值

MOV X,AX ;保存輸入值COMP:

CMP X,3 ;比較,X>3? JG GREATER ;X>3成立,轉(zhuǎn)“GREATER” CMP X,-3 ;比較,X<-3? JL GREATER ;X<-3成立,轉(zhuǎn)“GREATER”LESS: ;|X|≤3的程序段

MOV BX,AX ;BX←X SAL AX,1 ;AX←2X ADD AX,BX ;AX←2X+X SUB AX,5 ;AX←3X-5

JMP OUTPUT47GREATER: MOV AX,6 ;|X|>3的程序段OUTPUT: LEA DX,OUT_MSG ;結(jié)果的前導(dǎo)文字

CALL WRITEINT ;輸出計(jì)算結(jié)果

CALL CRLF ;輸出回車換行EXIT: MOV AX,4C00H INT 21HCODE ENDS END START484.2.2單分支選擇結(jié)構(gòu)如果選擇結(jié)構(gòu)的一個(gè)分支為“空”,這樣的程序流程稱為

“單分支選擇結(jié)構(gòu)”。合理地選擇Jcc指令所使用的條件,可以使程序更加流暢??梢园岩恍┗具x擇結(jié)構(gòu)程序改寫為單分支選擇結(jié)構(gòu)。49計(jì)算AX←|AX|的兩種判斷方法:50

……COMP:

MOV AX,6 ;預(yù)設(shè)AX=6

CMP X,3

;比較,X>3?

JG OUTPUT

;若X>3,轉(zhuǎn)OUTPUT輸出

CMP X,-3

;比較,X<-3?

JL OUTPUT

;若X<-3,轉(zhuǎn)OUTPUT輸出LESS: ;|X≤3的程序段

MOV AX,X

;AX←X …… ;AX←3X-5OUTPUT: LEA DX,OUT_MSG ;結(jié)果的前導(dǎo)文字

CALL WRITEINT ;輸出計(jì)算結(jié)果在例4-4中,可以將Y“預(yù)設(shè)”為6,一旦條件|X|>3成立,立即轉(zhuǎn)向OUTPUT輸出“預(yù)設(shè)”的結(jié)果,否則進(jìn)行相應(yīng)的計(jì)算。51[例4-5]將4位二進(jìn)制轉(zhuǎn)換成對(duì)應(yīng)的十六進(jìn)制字符 MOV AL,X CMP AL,9 JA ALPH ADD AL,30H JMP DONEALPH: ADD AL,37HDONE: MOV Y,AL MOV AL,X OR AL,30H CMP AL,‘9’ JBE DONE ADD AL,7DONE: MOV Y,AL52 選擇結(jié)構(gòu)一個(gè)分支的程序中又出現(xiàn)了選擇結(jié)構(gòu),這樣的

結(jié)構(gòu)稱為“復(fù)合選擇結(jié)構(gòu)”或者“嵌套選擇結(jié)構(gòu)”。

4.2.3復(fù)合選擇結(jié)構(gòu)排除法:每次判斷排除若干可能,留下一種可能情況進(jìn)行處理;確認(rèn)法:每次判斷確認(rèn)一種可能,對(duì)已確認(rèn)的情況進(jìn)行處理。53[例4-6]計(jì)算Y=SGN(X);方法a,逐項(xiàng)排除

CMP X,0JGE UN_MINUSMINUS:MOV Y,-1JMP DONEUN_MINUS:JE ZEROMOV Y,1JMP DONEZERO: MOV Y,0DONE: ……;方法b,逐項(xiàng)確認(rèn)

CMP X,0JG PLUSJE ZEROMINUS:MOV Y,-1JMP DONEPLUS:MOV Y,1JMP DONEZERO:MOV Y,0DONE: ……復(fù)合分支選擇結(jié)構(gòu)544.2.4多分支選擇結(jié)構(gòu)在選擇結(jié)構(gòu)程序里,如果可供選擇的程序塊多于兩個(gè),這樣的結(jié)構(gòu)稱為多分支選擇結(jié)構(gòu),如下圖(a)所示,下圖(b)是匯編語言程序的實(shí)現(xiàn)方法。55DATA SEGMENTPROMPT DB 0DH,0AH,“Inputanumber(1~3):$”MSG1 DB 0DH,0AH,“FUNCTION1EXECUTED.$”MSG2 DB 0DH,0AH,“FUNCTION2EXECUTED.$”MSG3 DB 0DH,0AH,“FUNCTION3EXECUTED.$”DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX[例4-7]從鍵盤上輸入數(shù)字“1”到“3”,根據(jù)輸入選擇對(duì)應(yīng)程序

塊執(zhí)行。56INPUT: LEA DX,PROMPT MOV AH,9 INT 21H ;輸出提示信息

MOV AH,1 INT 21H ;輸入一個(gè)數(shù)字

CMP AL,‘1’ JB INPUT ;“0”或非數(shù)字,重新輸入

JE F1 ;數(shù)字“1”,轉(zhuǎn)F1 CMP AL,‘2’ JE F2 ;數(shù)字“2”,轉(zhuǎn)F2 CMP AL,‘3’ JE F3 ;數(shù)字“3”,轉(zhuǎn)F3 JMP INPUT ;大于“3”,重新輸入57F1: LEA DX,MSG1 ;F1程序塊

JMP OUTPUTF2: LEA DX,MSG2 ;F2程序塊

JMP OUTPUTF3: LEA DX,MSG3 ;F3程序塊

JMP OUTPUTOUTPUT: MOV AH,9 INT 21H MOV AX,4C00H INT 21HCODE ENDS END START58DATA SEGMENTPROMPT DB0DH,0AH,“Inputanumber(1~3):$”MSG1 DB0DH,0AH,“FUNCTION1EXECUTED.$”MSG2 DB0DH,0AH,“FUNCTION2EXECUTED.$”MSG3 DB0DH,0AH,“FUNCTION3EXECUTED.$”ADDTBL DWF1,F2,F3DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA用地址表實(shí)現(xiàn)多分支59START:MOVAX,DATA MOV DS,AXINPUT:LEA DX,PROMPT MOV AH,9 INT 21H ;顯示提示信息

MOV AH,1 INT 21H ;輸入一個(gè)數(shù)字

CMP AL,‘1’ JB INPUT ;不正確輸入,重新輸入

CMP AL,‘3’ JA INPUT ;不正確輸入,重新輸入60

SUB AL,‘1’ ;將數(shù)字字符“1”到“3”轉(zhuǎn)換為0,1,2 SHL AL,1 ;轉(zhuǎn)換為0,2,4 MOV BL,AL MOV BH,0 ;轉(zhuǎn)入BX JMP ADDTBL[BX] ;間接尋址,轉(zhuǎn)移到對(duì)應(yīng)程序塊F1: LEA DX,MSG1 ;F1程序塊

JMP OUTPUT F2: LEA DX,MSG2 ;F2程序塊

JMP OUTPUTF3: LEA DX,MSG3 ;F3程序塊

JMP OUTPUT ;這條指令可以省略61OUTPUT: MOV AH,9 INT 21H MOV AX,4C00H INT 21HCODE ENDS END START62CODE SEGMENTASSUME CS:CODESTART: JMP BEGINX DB ? ;被測(cè)試的數(shù),匯編之前置入YES DB 0AH,0DH,“It’saevennumber.”,0AH,0DH,‘$’NO DB 0AH,0DH,“It’saoddnumber.”,0AH,0DH,‘$’BEGIN:PUSH CS POP DS例:判斷變量X的值是否為“偶數(shù)”63

TEST X,1 ;測(cè)試X的最低位,確定是否為偶數(shù)

JZ EVN ;ZF=1,該數(shù)是偶數(shù),轉(zhuǎn)向“EVN”O(jiān)DD: LEA DX,NO

;否則,該數(shù)是奇數(shù)

MOV AH,9 INT 21H ;輸出奇數(shù)的相關(guān)信息

JMP DONE ;跳過程序“EVN”EVN: LEA DX,YES

MOV AH,9 INT 21H

;輸出偶數(shù)的相關(guān)信息DONE: MOV AX,4C00H INT 21HCODE ENDS END START64

…… TEST X,1 ;測(cè)試X的最低位,確定是否為偶數(shù)

JZ EVN ;ZF=1,該數(shù)是偶數(shù),轉(zhuǎn)向“EVN”O(jiān)DD: LEA DX,NO

;否則,該數(shù)是奇數(shù)

JMP DONE ;跳過程序“EVN”EVN: LEA DX,YES

;該數(shù)是偶數(shù)DONE: MOV AH,9 INT 21H

;輸出該數(shù)的相關(guān)信息

MOV AX,4C00H ……如果兩個(gè)“平行”分支有相同的處理過程,可以把它們“合并”:65變量X取值93H,匯編、連接后運(yùn)行該程序,程序輸出:

It’saoddnumber.變量X取值94H,匯編、連接后運(yùn)行該程序,程序輸出:

It’saevennumber.664.3循環(huán)結(jié)構(gòu)程序4.3.1循環(huán)指令4.3.2計(jì)數(shù)循環(huán)4.3.3條件循環(huán)4.3.4多重循環(huán)67 循環(huán)結(jié)構(gòu)也稱為“重復(fù)結(jié)構(gòu)”,幾乎所有的應(yīng)用程序中都離不開循環(huán)結(jié)構(gòu)。循環(huán)一般由以下4個(gè)部分組成:(1)初始化部分:為循環(huán)做準(zhǔn)備,如累加器清零,設(shè)置地址指針和計(jì)數(shù)器的初始值等。(2)工作部分:實(shí)現(xiàn)循環(huán)的基本操作,也就是需要重復(fù)執(zhí)行的一段程序。(3)修改部分:修改指針、計(jì)數(shù)器的值,為下一次循環(huán)做準(zhǔn)備。(4)控制部分:判斷循環(huán)條件,結(jié)束循環(huán)或繼續(xù)循環(huán)。68計(jì)數(shù)循環(huán):循環(huán)的次數(shù)事先已知,用一個(gè)變量(寄存器

或存儲(chǔ)器單元)記錄循環(huán)的次數(shù)(稱為“循環(huán)計(jì)數(shù)

器”)。條件循環(huán):循環(huán)的次數(shù)事先并不確定,每次循環(huán)開始時(shí) 或結(jié)束后測(cè)試某個(gè)條件,根據(jù)這個(gè)條件是否滿足 來決定是否繼續(xù)下一次循環(huán)。按照循環(huán)結(jié)束的條件,有以下兩類循環(huán):69兩種結(jié)構(gòu)的循環(huán):WHILE循環(huán):進(jìn)入循環(huán)后,先判斷循環(huán)結(jié)束條件,條件滿足則退出循環(huán),循環(huán)次數(shù)最少為0次。DO-WHILE循環(huán):進(jìn)入循環(huán)后,先執(zhí)行工作部分,然后判斷循環(huán)繼續(xù)的條件,條件滿足則轉(zhuǎn)向工作部分繼續(xù)循環(huán),循環(huán)次數(shù)最少1次。7071LOOP Label ;CX←CX-1,若(CX)≠0,轉(zhuǎn)移到LabelLOOPZ/LOOPELabel

;CX←CX-1,若(CX)≠0且ZF=1,轉(zhuǎn)移到LabelLOOPNZ/LOOPNE Label

;CX←CX-1,若(CX)≠0且ZF=0,轉(zhuǎn)移到Label4.3.1循環(huán)指令 循環(huán)指令采用相對(duì)尋址方式,Label距離循環(huán)指令的下一條

指令必須在-128~+127B之內(nèi)。72

LOOPZ/LOOPE,LOOPNZ/LOOPNE指令的功能也可以由

Jcc指令實(shí)現(xiàn)。由于對(duì)CX先減1,后判斷,如果CX的初值為0,將循環(huán)

65536次。循環(huán)指令的執(zhí)行不影響標(biāo)志位。LOOP指令的功能可以用Jcc指令實(shí)現(xiàn):DEC CX ;CX←CX-1JNZ Label ;若(CX)≠0(也就是ZF=0),轉(zhuǎn)移到Label73計(jì)數(shù)循環(huán)是基本的循環(huán)組織方式,用循環(huán)計(jì)數(shù)器的值來控制循環(huán),有時(shí)候也可以結(jié)合其它條件共同控制。4.3.2計(jì)數(shù)循環(huán)[例4-8]從鍵盤上輸入一個(gè)字符串(不超過80個(gè)字符),將它

逆序后輸出。INCLUDE YLIB.HDATA SEGMENTBUFFER DB 81,?,81DUP(?)MESS DB 0AH,0DH,“Inputastringplease:$”DATA ENDS74CODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX LEA DX,MESS MOV AH,09H INT 21H ;輸出提示信息

MOV AH,0AH LEA DX,BUFFER INT 21H ;輸入字符串

CALL CRLF

LEA BX,BUFFER ;緩沖區(qū)首地址送BX MOV CL,BUFFER+1 MOV CH,0 ;輸入字符個(gè)數(shù)送CX(循環(huán)次數(shù))75

ADD BX,CX

INC BX ;計(jì)算字符串末地址送BX(指針)DISP: MOV DL,[BX] MOV AH,02H INT 21H ;逆序輸出一個(gè)字符

DEC BX ;修改指針

LOOP DISP ;計(jì)數(shù)循環(huán)

CALL CRLF ;輸出換行、回車,結(jié)束本行

MOV AX,4C00H INT 21HCODE ENDS END START76用總分減去最高分、最低分,最后除以5,得到需要的成績(jī)。求N個(gè)數(shù)據(jù)中最大值的方法:

預(yù)設(shè)一個(gè)“最大值”,

取出一個(gè)數(shù)據(jù)與這個(gè)“最大值”進(jìn)行比較,

如果數(shù)據(jù)大于“最大值”,則將該數(shù)據(jù)作為新的“最大值”。

進(jìn)行N次比較之后留下的就是這N個(gè)數(shù)據(jù)的最大值。預(yù)設(shè)的“最大值”的初值可以從N個(gè)數(shù)據(jù)中任取一個(gè),也可以根

據(jù)數(shù)據(jù)的范圍,取一個(gè)該范圍內(nèi)的最小的數(shù)。計(jì)算最小值的方法與此類似。[例4-10]從鍵盤上輸入七名裁判的評(píng)分(0~10),扣除一個(gè)最

高分,一個(gè)最低分,計(jì)算出其它五項(xiàng)評(píng)分的平均值(保留

一位小數(shù)),在顯示器上輸出。77INCLUDE YLIB.HDATA SEGMENTMESS1 DB 0DH,0AH,“Inputascore(0~10):$”MESS2 DB 0DH,0AH,“Thefinalscoreis:$”C5 DB 5MAX DB ?MIN DB ?SUM DB ?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX78

MOV SUM,0 ;累加器清零

MOV MAX,0 ;“最大值”預(yù)設(shè)為0 MOV MIN,255 ;“最小值”預(yù)設(shè)為255 MOV CX,7 ;循環(huán)計(jì)數(shù)器,初值7ONE: LEA DX,MESS1 CALL READDEC ;鍵盤輸入一個(gè)分?jǐn)?shù)

ADD SUM,AL ;累加

CMP MAX,AL ;與“最大值”比較

JA L1 MOV MAX,AL ;大于“最大值”則保留L1: CMP MIN,AL ;與“最小值”比較

JB L2 MOV MIN,AL ;小于“最小值”則保留L2: LOOP ONE ;計(jì)數(shù)循環(huán)79

MOV AL,SUM SUB AL,MAX SUB AL,MIN ;從總分中減去最大、最小值

MOV SUM,AL XOR AH,AH ;高8位清零

DIV C5 ;求平均值

PUSH AX ;保留余數(shù)(在AH中)

MOV AH,0 ;清余數(shù)

LEA DX,MESS2 CALL WRITEDEC ;輸出結(jié)果的整數(shù)部分80

MOV DL,‘.’ MOV AH,2 INT 21H ;輸出小數(shù)點(diǎn)

POP AX ;從堆棧彈出余數(shù)

SHL AH,1 ;計(jì)算小數(shù)部分:(AH÷5)×10=AH×2 MOV DL,AH OR DL,30H ;轉(zhuǎn)換成ASCII代碼

MOV AH,2 INT 21H ;輸出結(jié)果的小數(shù)部分

CALL CRLF ;輸出回車換行,結(jié)束本行

MOV AX,4C00H INT 21HCODE ENDS END START814.3.3條件循環(huán)DATA SEGMENTSTRING DB “Astringfortesting.”,0LENTH DW?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX[例4-8]字符串STRING以代碼0結(jié)束,求這個(gè)字符串的長(zhǎng)度(字符個(gè)數(shù))。82

LEA SI,STRING ;裝載字符串指針

MOV CX,0 ;設(shè)置計(jì)數(shù)器初值TST: CMP BYTEPTR[SI],0;比較

JE DONE ;字符串結(jié)束,轉(zhuǎn)向DONE保存結(jié)果

INC SI ;修改指針

INC CX ;計(jì)數(shù)

JMP TST

;轉(zhuǎn)向TST,繼續(xù)循環(huán)DONE: MOV LENTH,CX ;保存結(jié)果

MOV AX,4C00H INT 21HCODE ENDS END START83

……

LEA SI,STRING-1 ;裝載字符串指針

MOV CX,-1 ;裝載計(jì)數(shù)器初值TST: INC SI ;修改指針

INC CX ;計(jì)數(shù)

CMP BYTEPTR[SI],0 ;比較

JNE TST ;未結(jié)束,轉(zhuǎn)TST繼續(xù)循環(huán)

MOV LENTH,CX ;字符串結(jié)束,保存結(jié)果

……比較一下,您喜歡這種風(fēng)格嗎?84

……TST: CMP BYTEPTR[SI],0 ;比較

INC SI ;修改指針

INC CX ;計(jì)數(shù)

JNE TST ;轉(zhuǎn)向TST,繼續(xù)循環(huán)

……錯(cuò)在哪里?運(yùn)行結(jié)果會(huì)怎樣?85DATA SEGMENTARRAY DW 1,2,3,4,5,6,-1AVRG DW ? DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOVAX,DATA MOVDS,AX[例4-13]一維無符號(hào)字?jǐn)?shù)組ARRAY以-1作為數(shù)組結(jié)束標(biāo)志,

求這個(gè)數(shù)組各元素的平均值。86

LEA BX,ARRAY ;裝載數(shù)組指針

XOR CX,CX ;設(shè)置計(jì)數(shù)器初值

XOR DX,DX XOR AX,AX ;清累加器ONE: CMP WORDPTR[BX],-1 ;判數(shù)組是否結(jié)束

JE DONE ;數(shù)組結(jié)束,轉(zhuǎn)DONE,結(jié)束處理

ADD AX,[BX] ;累加

ADC DX,0 ;保留進(jìn)位

ADD BX,2 ;修改指針

INC CX ;數(shù)組元素個(gè)數(shù)計(jì)數(shù)

JMP ONE 87DONE: JCXZ NULL

;數(shù)組元素個(gè)數(shù)為0,不能求平均值

DIV CX ;計(jì)算數(shù)組平均值

MOV AVRG,AX ;保存結(jié)果

JMP EXITNULL: MOV AVRG,-1 ;數(shù)組為“空”,記平均值為-1EXIT: MOV AX,4C00H INT 21HCODE ENDS END START88DATA SEGMENTPOSITION DW ?STRING DB “Thisisastringforexample.”,0DATA ENDSCODE SEGMENTASSUME DS:DATA,CS:CODESTART: MOV AX,DATA MOV DS,AX[例4-14]查找字母’a’在字符串STRING中第一次出現(xiàn)的位置,

如果未出現(xiàn),置位置值為-1。89

MOV SI,-1 ;SI用作字符串字符指針

MOV CX,30 ;字符串長(zhǎng)度30L0: INC SI ;修改指針

CMP STRING[SI],‘a(chǎn)’ ;一個(gè)字符與’a’進(jìn)行比較

LOOPNE L0 ;字符串未結(jié)束,未找到,繼續(xù)

JNE NOTFOUND ;未找到,轉(zhuǎn)“NOTFOUND” MOV POSITION,SI ;保存位置值

JMP EXITNOTFOUND:MOV POSITION,-1 ;未找到,置位置值為-1EXIT: MOV AX,4C00H INT 21HCODE ENDS END START90字符串內(nèi)找到字符’a’:循環(huán)結(jié)束時(shí)ZF=1,SI內(nèi)是字符的出

現(xiàn)位置(從0開始);字符串內(nèi)未找到字符’a’:循環(huán)結(jié)束時(shí)ZF=0,SI內(nèi)是字符串

的長(zhǎng)度-1(30-1=29)。程序使用LOOPNE指令來控制循環(huán),既有計(jì)數(shù)控制,又有條件控制。循環(huán)結(jié)束有兩種可能性:對(duì)于LOOPZ/LOOPE,LOOPNZ/LOOPNE控制的循環(huán),一般應(yīng)在循環(huán)結(jié)束后用條件轉(zhuǎn)移指令分開這兩種情況,分別處理。914.3.4多重循環(huán)如果一個(gè)循環(huán)的循環(huán)體內(nèi)包含了另一個(gè)循環(huán),稱這個(gè)循環(huán)為“多重循環(huán)”,各層循環(huán)可以是計(jì)數(shù)循環(huán)或者條件循環(huán)。92[例4-16]打印20H~7FH之間的ASCII字符表。

!“#$%&‘()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~

93打印格式:每行16個(gè)字符,共6行。打印1行:打印1個(gè)字符的過程重復(fù)16次,構(gòu)成一個(gè)計(jì)數(shù)循環(huán)(內(nèi)循環(huán))。打印6行:打印1行字符的過程重復(fù)6次,構(gòu)成另一個(gè)計(jì)數(shù)循環(huán)(外循環(huán))。94INCLUDE YLIB.HCODE SEGMENTASSUME CS:CODE,DS:CODESTART: MOV BL,20H ;第一個(gè)字符的ASCII代碼

MOV CH,6 ;行數(shù)計(jì)數(shù)器初值;============打印一行循環(huán)開始=============L0: CALL CRLF ;開始一個(gè)新行

MOV CL,16 ;列計(jì)數(shù)器初值

95;-------------------打印一個(gè)字符的循環(huán)開始---------------------L1: MOV DL,BL ;裝入一個(gè)字符ASCII代碼

MOV AH,2 INT 21H ;輸出一個(gè)字符

MOV DL,20H MOV AH,2 INT 21H ;輸出一個(gè)空格

INC BL ;準(zhǔn)備下一個(gè)待輸出的ASCII碼

DEC CL ;列數(shù)計(jì)數(shù)L11: JNZ L1 ;列數(shù)未滿(本行未完),轉(zhuǎn)L1繼續(xù);---------------------打印一個(gè)字符的循環(huán)結(jié)束----------------------96

DEC CH ;行數(shù)計(jì)數(shù)L00: JNZ L0 ;行數(shù)未滿,轉(zhuǎn)L0繼續(xù);=============打印一行的循環(huán)結(jié)束============ CALL CRLF ;結(jié)束最后一行

MOV AX,4C00H INT 21HCODE ENDS END START97

…… MOV BL,20H ;第一個(gè)字符的ASCII代碼

MOV CX,6 ;行數(shù)計(jì)數(shù)器初值

;=============打印一行循環(huán)開始==============L0: CALL CRLF ;開始一個(gè)新行

PUSH CX ;保存CX中的行計(jì)數(shù)器值

MOV CX,16 ;CX中置入列計(jì)數(shù)器初值借助于堆棧,將CX“分身”為兩個(gè)計(jì)數(shù)器98;--------------------打印一個(gè)字符的循環(huán)開始--------------------L1: MOV DL,BL ;裝入一個(gè)字符ASCII代碼

…… ……L11: LOOP L1 ;列數(shù)未滿(本行未完),轉(zhuǎn)L1繼續(xù);-------------------打印一個(gè)字符的循環(huán)結(jié)束-----------------------

POP CX ;恢復(fù)CX為行計(jì)數(shù)器L00: LOOP L0 ;行數(shù)計(jì)數(shù),行數(shù)未滿,轉(zhuǎn)L0繼續(xù);==============打印一行的循環(huán)結(jié)束============== ……99[例4-17]用“冒泡”的方法對(duì)數(shù)組P的元素排序,按從小到大的順序排列。排序遍數(shù)本遍整序前第1次整序后第2次整序后第3次整序后第4次整序后

1

32168485

16328485

16328485

16328845

16328584

2

16328584

16328584

16832584

168532

84

3

168532

84

816532

84

851632

84

4

851632

84

58

1632

84

100INCLUDE YLIB.HDATA SEGME

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論