8086指令系统---串处理指令
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所指示的数据段中的数据传送到由DI指示的附加段中,本例将源串和目的串都设置在同一个段DATSEG中,因此,DS和ES都定义为DATSEG。
(1)用STOS指令将0AAH存入100个存储器字节;
(2)利用LODS指令测试这些存储器单元的内容是否是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个字节是通过执行50次的字操作来完成的。在测试部分,LODSB指令把存储器字节的内容取到AL,并和数据0AAH异或,如果这两个数相同,ZF=1,则继续进行下一个数的测试。如果两数不同,则ZF=0,转去执行显示字符串的BIOS功能调用。显示字符串用了三条指令,首先在AH中装入的显示字符串的功能号09,然后在DX中装入字符串的地址,再用INT 21H调用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指向的第一对字符时,根据比较结果设置ZF并使(SI)+1,(DI)+1以及(CX)-1。因为第一对字符是相同的(L),所以ZF=1,于是由REPE控制再重复比较下一对字符。直到比较第四对字符E和L时,由于它们不相同,ZF设置为0,所以串比较结束。打印的信息应是: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中的每个字符进行比较,如果串中字符与M不同,则DI增量,CX减量,继续进行下一个字符的扫描比较,一直到发现M或CX=0为止。在本例中,因为发现了M,比较的结果使ZF=1,同时DI已指向了下一个字符I,所以DI退回一个字符位置(DEC DI),并用N取代M。
8086指令系统串处理指 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)