欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

汇编实验:查找匹配字符串

程序员文章站 2022-07-13 21:46:06
...

题目要求:

查找匹配字符串
程序接受用户键入的一个关键字以及一个句子。如果句子中不含关键字则显示‘no math’;如果句子中包含关键字则显示‘math’,且把该字在句子中的位置用十六进制数显示出来。

思路:
  1. 暴力匹配,对于字符串每个字符开头均进行匹配
  2. 利用串操作指令可简化代码,减少循环
  3. 注意比较次数为 字符串长度-关键字长度+1
  4. 若匹配到关键字,则当前 BX寄存器内容 存放即为 当前关键字所在位置 - 1
  5. 输出进制转换:
    (1)十进制:将计数器中内容除以10,对个位和十位分别进行 +30H 并输出
    (2)十六进制:将计数器内容除以16,并对个位,十位分别判断是否 < 10 ,若小于则 +30H 转化为数字字符并输出,否则 +37H 转化为对应十六进制大写字母字符。
扩展:删除字符串中首次出现的关键字
  1. 将原字符串复制到新的字符串当中
  2. 利用 REP MOVSB 指令进行删除操作
  3. 在新字符串中找到首次出现关键字,并依次将关键字之后字符向前移动,循环次数为 字符串长度 (ACT1)- 关键长度(ACT2) - 已经匹配字符个数(BX)
  4. 最后在移除关键字并完成 REP MOVSB 操作后在串后进行 MOV BYTE PTR[DI],’$' 操作,添加 ’$' 表示字符串终止。
实验代码:
DATAS SEGMENT
    ;此处输入数据段代码  
    INPUT1 DB 13,10,'Please input a string:','$'
    INPUT2 DB 13,10,'Please input a key:','$'
    ERROR DB 13,10,'Input error!','$'
    
    BUFFER LABEL BYTE
    	   MAX1 DB 80
    	   ACT1 DB ?
    	   STOKN1 DB 80 DUP(?)
    	   
    KEY	LABEL BYTE
    	MAX2 DB 80
    	ACT2 DB ?
    	STOKN2 DB 80 DUP(?)	 
    
    TEMP LABEL BYTE
    	MAX3 DB 80
    	ACT3 DB ?
    	STOKN3 DB 80 DUP(?)
    	
    DIVIDING_LINE_1 DB 13,10,'**********************************',13,10,'$'	;此处分割线
    DIVIDING_LINE_2 DB 13,10,'----------------------------------','$'	;此处分割线
   	
    ASK_1 DB 13,10,'Whether to perform string matching?','$'
    ASK_2 DB 13,10,'Please input Y/N:','$'
    
    
    MATCH  DB 13,10,'Match!','$'
    NOMATCH DB 13,10,'No Match','$'
    LOCATION_1 DB 13,10,'Keyword location (Hex) is:','$'
    LOCATION_2 DB 13,10,'Keyword location (Decimal) is:','$'
    RESULT DB 13,10,'The content of the new string is:','$'
    CRLF DB 13,10,'$'
    CHAR DB '$'
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:DATAS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV ES,AX
    
    LEA DX,DIVIDING_LINE_1		;回车换行
   	MOV AH,09H
   	INT 21H
   	
    LEA DX,ASK_1
   	MOV AH,09H
   	INT 21H
    
    LEA DX,ASK_2
   	MOV AH,09H
   	INT 21H
   	
   	MOV AH,01H
   	INT 21H
   	   	
   	CMP AL,'Y'
   	JE BEGIN_1
   	
   	CMP AL,'N'
   	JE END_0
   	JNE ERROR_1
   	
BEGIN_1:
   	LEA DX,INPUT1	;提示输入
   	MOV AH,09H
   	INT 21H
   	
   	LEA DX,BUFFER	;输入字符串
   	MOV AH,0AH
   	INT 21H
   	 
   	LEA DX,INPUT2	;提示输入
   	MOV AH,09H
   	INT 21H
   	
   	LEA DX,KEY		;输入关键字
   	MOV AH,0AH
   	INT 21H
   	
   	LEA DX,DIVIDING_LINE_2		;回车换行
   	MOV AH,09H
   	INT 21H
   	
   	MOV CL,ACT2		;CL存放关键字长度
   	
   	MOV AH,ACT1
   	SUB AH,CL
   	JB ERROR_1		;字符串长度小于关键字长度,直接error
   	
   	MOV DH,AH		;字符串长度减关键字长度作为循环次数
   	ADD DH,1
   	
   	LEA DI,STOKN1	;初始化DI,为字符串指针
   	LEA SI,STOKN2	;初始化SI,为关键字指针
	MOV BX,0		;初始化字符串偏移量

CMP_SEG:
	CLD				;设置SI,DI移动方向为+1
   	REPZ CMPSB		;比较字符串和关键字
   	JZ MATCH_1		;匹配成功,跳转至MATCH_1
   	JNZ LOOP_1		;匹配失败,循环继续匹配
   	
LOOP_1:
	INC BX			;字符串偏移量
	LEA DI,STOKN1	;重置DI
   	LEA SI,STOKN2	;重置SI
   	MOV CL,ACT2		;CL存放关键字长度
   	ADD DI,BX		;确定新的字符串起始位置
	DEC DH 			;循环次数减一
   	CMP DH,0		;判断循环是否终止
   	JE NO_MATCH		;若循环终止还未匹配,则跳转至NO_MATCH
	JNE CMP_SEG 	;否则继续匹配
   	
MATCH_1:
	LEA DX,MATCH	;匹配成功
	MOV AH,09H
	INT 21H
	
	LEA DX,LOCATION_1
	MOV AH,09H
	INT 21H
	
	MOV AX,BX
	PUSH BX				;进栈保护数据
	INC AX				;使起始位置从一开始
	CALL PRINT_2		;将关键字所在位置以十六进制数形式打印
	
	LEA DX,LOCATION_2
	MOV AH,09H
	INT 21H
	
	POP BX				;出栈恢复数据
	MOV AX,BX
	PUSH BX
	INC AX
	CALL PRINT_1		;将关键字所在位置以十进制数形式打印
	
	POP BX
	CALL DELETE_KEY
	
	
	JMP START
	
NO_MATCH:
	LEA DX,NOMATCH		;匹配失败
	MOV AH,09H
	INT 21H
	
	
	JMP START
ERROR_1:
	LEA DX,ERROR		;输入错误
	MOV AH,09H
	INT 21H
	
	
	JMP START

PRINT_1:    	;两位十进制输出
	MOV AH,0  	;对于超过9个数的字符,ASCII中并没有直接与之对应的字符,因此应分别输出两位数的各位和十位。
	MOV BL,10
	DIV BL    	;将AX中内容除以10,商放在AL,余数放在AH
	ADD AL,30H  ;将个位数+30H转化为数字字符
	MOV BH,AH
	MOV DL,AL
	MOV AH,02H  ;打印个位数
	INT 21H
	MOV AL,BH 
	ADD AL,30H  ;将十位数转化为数字字符
	MOV DL,AL 
	MOV AH,02H  ;打印十位数
	INT 21H
	RET

PRINT_2:
	MOV AH,0  ;对于超过9个数的字符,ASCII中并没有直接与之对应的字符,因此应分别输出两位数的各位和十位。
	MOV BL,16
	DIV BL    ;将AX中内容除以16,商放在AL,余数放在AH
	MOV BH,AH
	CMP AL,10
	JB NUMBER_1
	JAE LETTER_1
  NUMBER_1:
	ADD AL,30H  ;将个位数+30H转化为数字字符
	JMP OUTPUT_1
  LETTER_1:
  	ADD AL,37H	;将个位数+37H转化为字母字符
  OUTPUT_1:
	MOV DL,AL
	MOV AH,02H  ;打印个位数
	INT 21H
	
	MOV AL,BH 
	CMP AL,10
	JB NUMBER_2
	JAE LETTER_2
  NUMBER_2:
	ADD AL,30H  ;将个位数+37H转化为字母字符
	JMP OUTPUT_2
  LETTER_2:
  	ADD AL,37H
  OUTPUT_2:
	MOV DL,AL 
	MOV AH,02H  ;打印十位数
	INT 21H
	RET
	
	
DELETE_KEY:			;删除字符串中关键字
	LEA SI,STOKN1	;复制原字符串到STOKN3
	LEA DI,STOKN3
	MOV CL,ACT1
	MOV CH,0
	CLD
	REP MOVSB
	
	LEA DI,STOKN3	;删除字符串中关键字
	ADD DI,BX		;确定删除位置
	
	LEA SI,STOKN1	;确定删除位置字符
	ADD SI,BX
	MOV DL,ACT2
	MOV DH,0
	ADD SI,DX
	
	MOV CL,ACT1
	SUB CL,DL
	SUB CX,BX
	
	CLD
	REP MOVSB
	
	MOV BYTE PTR[DI],'$'	;在删除之后字符串尾加'$',表示字符串终止
	
	LEA DX,RESULT			;回车换行
	MOV AH,09H
	INT 21H
	
	LEA DX,STOKN3			;输出删除关键字后字符串
	MOV AH,09H
	INT 21H
	
	RET
END_0:
	MOV AH,4CH
	INT 21H
CODES ENDS
    END START
    
执行结果

汇编实验:查找匹配字符串
汇编实验:查找匹配字符串
汇编实验:查找匹配字符串

相关标签: 字符串