8086指令系統(tǒng)---串處理指令
DATSEG SEGMENT
DATAX DB ABCDEFGHIJKLMNOPQRST
DATAY DB 20 DUP(?)
DATSEG ENDS
; - - - - - - - - - - - - - - - - - - - -
CODSEG SEGMENT
ASSUME CS:CODSEG,DS:DATSEG,ES:DATSEG
START: MOV AX,DATSEG
MOV DS,AX ; initialize the data segment
MOV ES,AX ; initialize the extra segment
CLD ; clear direction flag for autoincrement
MOV SI,OFFSET DATAX ; load the source pointer
MOV DI,OFFSET DATAY ; load the destination pointer
MOV CX,20 ; load the counter
REP MOVSB ; repeat until CX becomes zero
MOV AX,4C00H ; return to DOS
INT 21H
CODSEG ENDS
END START
串傳送指令將SI所指示的數(shù)據(jù)段中的數(shù)據(jù)傳送到由DI指示的附加段中,本例將源串和目的串都設(shè)置在同一個段DATSEG中,因此,DS和ES都定義為DATSEG。
?。?)用STOS指令將0AAH存入100個存儲器字節(jié);
?。?)利用LODS指令測試這些存儲器單元的內(nèi)容是否是0AAH,如果不是則顯示"bad memory"。
DTSEG SEGMENT
DATAM DB 100 DUP(?)
MESG DB bad memory, $
DTSEG ENDS
; - - - - - - - - - - - - - - - - - -
CDSEG SEGMENT
ASSUME CS:CDSEG,DS:DTSEG,ES:DTSEG
START: MOV AX,DTSEG ; initialize
MOV DS,AX ; DS register
MOV ES,AX ; and ES register
CLD ; clear DF for increment
MOV CX,50 ; load the counter(50 words)
MOV DI,OFFSET DATAM ; load the pointer for destination
MOV AX,0AAAAH ; load the pattern
REP STOSW ; repeat until CX=0
; bring in the pattern and test it one by one
MOV SI,OFFSET DATAM ; load the pointer for source
MOV CX,100 ; load the counter(100 bytes)
AGAIN: LODSB ; load into AL from DS:SI
XOR AL,0AAH ; is pattern the same?
JNZ OVER ; if not the same, then exit
LOOP AGAIN ; continue until CX=0
JMP EXIT ; exit program
OVER: MOV AH,09 ; display
MOV DX,OFFSET MESG ; the message
INT 21H ; routine
EXIT: MOV AX,4C00H ; return to DOS
INT 21H
CDSEG ENDS
END START
把0AAH存入100個字節(jié)是通過執(zhí)行50次的字操作來完成的。在測試部分,LODSB指令把存儲器字節(jié)的內(nèi)容取到AL,并和數(shù)據(jù)0AAH異或,如果這兩個數(shù)相同,ZF=1,則繼續(xù)進(jìn)行下一個數(shù)的測試。如果兩數(shù)不同,則ZF=0,轉(zhuǎn)去執(zhí)行顯示字符串的BIOS功能調(diào)用。顯示字符串用了三條指令,首先在AH中裝入的顯示字符串的功能號09,然后在DX中裝入字符串的地址,再用INT 21H調(diào)用BIOS例程,完成顯示指定字符串的功能。
(1)如果相同,則顯示"The spelling is correct";
(2)如果不同,則顯示"Wrong splling"。
DATASEG SEGMENT
DAT_DICT DB LABEL
DAT_TYPE DB LABLE
MESS1 DB The spelling is correct ,$
MESS2 DB Wrong spelling ,$
DATASEG ENDS
; - - - - - - - - - - - - - - - - - - - - -
CODESEG SEGMENT
ASSUME CS:CODESEG,DS:DATASEG,ES:DATASEG
START: MOV AX,DATASEG
MOV DS,AX ; initialize the data segment
MOV ES,AX ; initialize the extra segment
CLD ; DF=0 for autoincrement
MOV SI,OFFSET DAT_DICT ; SI is source pointer
MOV DI,OFFSET DAT_TYPE ; DI is destination pointer
MOV CX,05 ; load the counter
REPE CMPSB ; repeat as long as equal or until CX=0
JE OVER ; if ZF=1 then display mess1
MOV DX,OFFSET MESS2 ; if ZF=0 then display mess2
JMP DISP
OVER: MOV DX,OFFSET MESS1
DISP: MOV AH,09 ; display message
INT 21H
MOV AX,4C00H ; return to DOS
INT 21H
CODSEG ENDS
END START
用CMPSB指令可將兩個串中的字符逐一比較,在比較SI和DI指向的第一對字符時,根據(jù)比較結(jié)果設(shè)置ZF并使(SI)+1,(DI)+1以及(CX)-1。因為第一對字符是相同的(L),所以ZF=1,于是由REPE控制再重復(fù)比較下一對字符。直到比較第四對字符E和L時,由于它們不相同,ZF設(shè)置為0,所以串比較結(jié)束。打印的信息應(yīng)是:Wrong spelling 。
DATA SEGMENT
NAME DB HU DAMING, $
DATA ENDS
; - - - - - - - - - - - -
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA
START: MOV AX,DATA
MOV DS,AX ; initialize the data segment
MOV ES,AX ; initialize the extra segment
CLD ; DF=0 for autoincrement
MOV AL,M
MOV DI,OFFSET NAME ; DI is destination pointer
MOV CX,09 ; load the counter
REPNE SCASB ; repeat as long as equal or until CX=0
JNE DISP ; if ZF=0 then display name
DEC DI ; decrement to point at M
MOV BYTE PTR [DI],N ; replace M with N
DISP: MOV AH,09 ; display the corrected name
MOV DX,OFFSET NAME
INT 21H
MOV AX,4C00H ; return to DOS
INT 21H
CODE ENDS
END START
本例中,AL寄存器中的字符M與NAME中的每個字符進(jìn)行比較,如果串中字符與M不同,則DI增量,CX減量,繼續(xù)進(jìn)行下一個字符的掃描比較,一直到發(fā)現(xiàn)M或CX=0為止。在本例中,因為發(fā)現(xiàn)了M,比較的結(jié)果使ZF=1,同時DI已指向了下一個字符I,所以DI退回一個字符位置(DEC DI),并用N取代M。
評論