今天调试汇编程序,要求是输入一个关键字,再输入一句话,如果这句话里面含有这个关键字返回match,没有这句话返回no match。在机子上做了好久好久,都因体力不支而放弃,今天我尝试先看懂网上相关的程序,学习到必须用到的代码后,自己在纸上写起来代码,一遍又一遍,果然还是在在纸上的效率比较高一些啊,当我思考的比较成熟时,敲到了电脑上,只有三个错误,改了几下就成功了啊,成功了啊,第一次用这么短的时间来调试程序,真是兴奋啊,仔细回想,之前也有一次相似经历,那是一次数据结构实验,要求设计一个递归程序,最头疼的递归程序使我望而却步啊,可是在自习室呆了不到一个小时的时间竟然把程序在纸上写出来了,在机器上很快就调通了。再回想,大神们介绍经验的时候都说先在纸上谢谢,再上机,果然不假啊。人在电脑前面就是有一种惰性,惰性啊。下面是我的程序:
;--------------------------hui----------------
CRLF MACRO
MOV AH,2
MOV DL,0DH
INT 21H ;换行(宏定义)
MOV AH,2
MOV DL,0AH
INT 21H
ENDM
;------------------------------------------
S_SHOW MACRO STRING
MOV AH,9 ;打印字符串(宏定义)
MOV DX,OFFSET STRING
INT 21H
ENDM
;-----------------------------------------
S_IN MACRO BUFF
MOV AH,10
MOV DX,OFFSET BUFF ;接收一个输入(宏定义)
INT 21H
ENDM
;-------------------------------------------
DATA SEGMENT
MESS1 DB 'MATCH',0DH,0AH,'$'
MESS2 DB 'NO MATCH',0DH,0AH,'$'
MESS3 DB 'Enter key word:',0,'$'
MESS4 DB 'Enter Sentence:',0,'$' ;数据段定义
KEY DB 100,?,100 DUP(0)
SENTENCE DB 100,?,100 DUP(0)
DATA ENDS
;------------------------------------------------
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
PUSH AX
SUB AX,AX
MOV AX,DATA
MOV DS,AX ;赋值数据段
;------------------------
S_SHOW MESS3
S_IN KEY
CRLF
GO:
S_SHOW MESS4
S_IN SENTENCE
CRLF
MOV CH,[SENTENCE+1]-[KEY+1]
INC CH ;初始化句子长度计数器
MOV BX,OFFSET SENTENCE+2 ;初始化句子指针
REBEGIN:
MOV CL,KEY+1 ;初始化关键字长度计数器
MOV SI,OFFSET KEY+2 ;初始化关键字指针
MOV DI,BX ;获得本轮比较当前句子指针
EXE:
PUSH DI
PUSH SI
MOV DI, WORD PTR[DI]
MOV SI, WORD PTR[SI]
CMP DI,SI ;比较si与di指针往后一个字节是否相等
JE MATCH1 ;如果相等转到match1处理
DEC CH ;-----------
INC CH ;测试句子是否扫描完毕
JE EXIT ;-----------
DEC CH ;句子计数器-1
INC BX ;当前正在比较指针后移一下
JMP REBEGIN ;进入下一次比较
MATCH1:
DEC CL ;关键字计数器-1
JE MATCH ;匹配成功,调到match处执行
INC DI ;匹配未结束,句子指针后移一下
INC SI ; 关键字指针后移
JMP EXE ;跳转到exe处比较
MATCH :
S_SHOW MESS1 ;显示匹配
CRLF
JMP GO ;跳转到开始
EXIT:
S_SHOW MESS2 ;显示不匹配
CRLF
JMP GO ;跳转到开始
;------------------------
CODE ENDS
END START
突然发现如果关键字匹配句子中的关键字时输出匹配关键字的位置。我竟然没实现,好了,现在补上,输出数的要求是十六进制,看起来这显示要费一番力气了,要把二进制显示成十六进制,这里用到了求与运算指令和右移运算指令,求与运算是 and dest,xx dest可以是通用寄存器,xx是要作与运算的十六进制数,右移指令逻辑右移指令 SHR
格式: SHR OPRD1,COUNT
----
功能: 本指令实现由COUNT决定次数的逻辑右移操作,每次移位时,最高位补0,最低位移至
---- 标志位CF中.
说明: 1. 其中OPRD1为目的操作数,可以是通用寄存器或存储器操作数.
----
2. COUNT代表移位的次数(或位数).移位一次,COUNT=1;移位多于1次时, COUNT=(CL),(CL)中为移位的次数.
3. 影响标志位OF,PF,SF,ZF,CF.
下面是我的代码,小写是新加的
;------------------------------------------
CRLF MACRO
MOV AH,2
MOV DL,0DH
INT 21H ;换行(宏定义)
MOV AH,2
MOV DL,0AH
INT 21H
ENDM
;------------------------------------------
S_SHOW MACRO STRING
MOV AH,9 ;打印字符串(宏定义)
MOV DX,OFFSET STRING
INT 21H
ENDM
;-----------------------------------------
S_IN MACRO BUFF
MOV AH,10
MOV DX,OFFSET BUFF ;接收一个输入(宏定义)
INT 21H
ENDM
;-------------------------------------------
DATA SEGMENT
MESS1 DB 'MATCH',0DH,0AH,'$'
MESS2 DB 'NO MATCH',0DH,0AH,'$'
MESS11 DB 'Match at the locaton',0,'$'
MESS22 DB 'H of the sentence',0,'$'
MESS3 DB 'Enter key word:',0,'$'
MESS4 DB 'Enter Sentence:',0,'$' ;数据段定义
KEY DB 100,?,100 DUP(0)
SENTENCE DB 100,?,100 DUP(0)
DATA ENDS
;------------------------------------------------
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
PUSH AX
SUB AX,AX
PUSH BX
SUB BX,BX
MOV AX,DATA
MOV DS,AX ;赋值数据段
;------------------------
S_SHOW MESS3
S_IN KEY
CRLF
GO:
sub dx,dx
S_SHOW MESS4
S_IN SENTENCE
CRLF
MOV CH,[SENTENCE+1]-[KEY+1]
INC CH ;初始化句子长度计数器
MOV BX,OFFSET SENTENCE+2 ;初始化句子指针
REBEGIN:
MOV CL,KEY+1 ;初始化关键字长度计数器
MOV SI,OFFSET KEY+2 ;初始化关键字指针
MOV DI,BX ;获得本轮比较当前句子指针
EXE:
CMP CH,CL
JB EXIT
PUSH DI
PUSH SI
MOV DI, WORD PTR[DI]
MOV SI, WORD PTR[SI]
CMP DI,SI ;比较si与di指针往后一个字节是否相等
JE MATCH1 ;如果相等转到match1处理
DEC CH ;-----------
INC CH ;测试句子是否扫描完毕
JE EXIT ;-----------
DEC CH ;句子计数器-1
INC BX ;当前正在比较指针后移一下
JMP REBEGIN ;进入下一次比较
MATCH1:
DEC CL ;关键字计数器-1
JE MATCH ;匹配成功,调到match处执行
INC DI ;匹配未结束,句子指针后移一下
INC SI ; 关键字指针后移
JMP EXE ;跳转到exe处比较
MATCH :
S_SHOW MESS1 ;显示匹配
S_SHOW MESS11
MOV DX,OFFSET sentence
push bx
sub Bx,dx
sub bx,2
mov dx,bx
push dx
shr dx,1
shr dx,1
shr dx,1
shr dx,1
cmp dx,9
ja anine2
a3:
cmp dx,9
jb bnine2
a4:
mov ah,02h
mov al,40h
int 21h
pop dx
and dx,0fh
cmp dx,9
ja anine1
a1:
cmp dx,9
jb bnine1
a2:
mov ah,02h
mov al,40
int 21h
S_SHOW MESS22
CRLF
pop bx
JMP GO ;跳转到开始
anine1:
add dx,37h
jmp a1
bnine1:
add dx,30h
jmp a2
anine2:
add dx,37h
jmp a3
bnine2:
add dx,30h
jmp a4
EXIT:
S_SHOW MESS2 ;显示不匹配
CRLF
JMP GO ;跳转到开始
;------------------------
CODE ENDS
END START