⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 32060624_王克_asmhomework_3.asm

📁 汇编语言 参考书 包含作业与答案 从入门到精通 通俗易懂
💻 ASM
字号:
;----------------------------------------------------------------
;        ╭══════┤    32060624___王克	         ├═════╮
;        ║          						     ║
;        ║             					     ║
;       ║              ★ 汇编语言 第三次作业 ★                   ║
;       ║      |---------------------------------------------|     ║
;       ║ 							     ║
;        ║                               2004.11.25                 ║
;        ║                                                          ║
;        ╰ ════════════════════════════╯
;汇编程序说明:
;	1.完全实现词典功能,可进行查找任意长度的单词,
;	2.从控制台输入一个单词,如果已存在此单词,则打印出相近的单词及位置
;	3.词典保存在文件中,为CET-4的词汇
;	4.对边界情况均做了处理,词典大小不大于64K。
;	5.程序用了大量的子程序,但结构还是很混乱。有待再思考。
;									2004.11.25 
;━┅━┅━┅━┅━┅━┅━┅━┅━━┅━┅━┅━┅━┅━┅━┅━━┅━┅━━┅━
.MODEL 	SMALL

STACK	SEGMENT	STACK
	BYTE	100 DUP(?)
STACK 	ENDS

DATA	SEGMENT	PARA		;用户交互信息
	msg_input_word		byte	0dh,0ah,'Please input the word you want to scan or insert(NOT NULL):  ','$'
	msg_open_error		byte	0dh,0ah,'Sorry,Dict lost.',0dh,0ah,'$'
	msg_read_error		byte	0dh,0ah,'Sorry,read file error.',0dh,0ah,'$'
	msg_find_word		byte	2 dup(0dh,0ah),'I seek you in the Dic in line  ','$'
	msg_insert_ok		byte	2 dup(0dh,0ah),'I insert you into the Dic in line: ','$'
	msg_disp_word		byte	3 dup(0dh,0ah),'OK! Show some near words to you:',0dh,0ah,'$'
	msg_save_ok		byte	2 dup(0dh,0ah),'OK! Save file success!',0dh,0ah,'$'
	msg_Esc			byte	2 dup(0dh,0ah),'Press ESC to quit. else to continue seek...',0dh,0ah,'$'
	dict_file_name		BYTE	'DICT.TXT',0
				;数据
	dict_file_handle	WORD	0
	dict_word_len		word	0
	word_max_len		byte	64,0
	insert_word		BYTE	32 DUP(0),'$'
	insert_word_len		word	0
	dict_data_len		word	0
	len_equal		byte	0
	line_num		word	0
	line_buffer		byte	5 dup(?),'$'
	dict_data_buffer	BYTE	3000H DUP(0),'$'	
	buffer_len		equ	$-dict_data_buffer
DATA	ENDS

CODE	SEGMENT	PARA
	ASSUME	CS:CODE,DS:DATA,SS:STACK
MAIN	PROC	FAR
	MOV	AX,DATA		;初始化DS,ES
	MOV	DS,AX
	MOV	ES,AX
EXIT_QUERY:			;判断用户是否要退出,不是则继续查询
	LEA	DX,MSG_ESC
	MOV	AH,09H
	INT 21H
	
	MOV	AH,10H
	INT 16H	
	CMP	AH,01H
	JNE	CONTINUE
	CALL	RETURN		;是ESC则返回DOS	
CONTINUE:
	CALL	GET_WORD	;从键盘读入要查找或插入的单词并处理,最长64位
	CMP	INSERT_WORD_LEN,0	;判断输入是否为空
	JE	CONTINUE	

	CALL	OPEN_FILE	;打开文件
	CALL	READ_FILE	;读入缓冲区
	CALL	CLOSE_FILE	;关闭文件

	CALL	SCAN_FILE	;开始查找单词,不存在则插入。并显示

	CALL	SAVE_FILE	;保存文件
MAINOK:
	CALL	RETURN		;返回DOS
	
MAIN	ENDP
;*******************************************************
GET_WORD	PROC	NEAR		;从键盘读入要查找或插入的单词并处理,最长64位
	MOV	DX,OFFSET MSG_INPUT_WORD
	MOV	AH,09H
	INT 21H
	
	MOV	AH,0AH
	LEA	DX,WORD_MAX_LEN
	INT 21H

	MOV	AL,WORD_MAX_LEN+1	;保存读入单词的长度
	XOR	AH,AH
	MOV	INSERT_WORD_LEN,AX	
	RET
GET_WORD	ENDP
;********************************************************
OPEN_FILE	PROC	NEAR
	MOV	DX,OFFSET DICT_FILE_NAME	;打开所读文件
	MOV	AL,2H
	MOV	AH,3DH
	INT 21H	
	JC	OPEN_FILE_ERROR
	MOV	DICT_FILE_HANDLE,AX		;保存文件句柄
	JMP	OPENOK	
OPEN_FILE_ERROR:
	LEA	DX,MSG_OPEN_ERROR	;打开文件错误处理
	MOV	AH,09H
	INT 21H
	CALL	RETURN
OPENOK:		
	RET
OPEN_FILE	ENDP
;*******************************************************
READ_FILE	PROC	NEAR

	MOV	BX,DICT_FILE_HANDLE
	MOV	CX,BUFFER_LEN			;最多读入的字节数
	LEA	DX,DICT_DATA_BUFFER
	MOV	AH,3FH
	INT 21H
	JC	READ_FILE_ERROR
	MOV	DICT_DATA_LEN,AX	;保存实际读进的字节数
	LEA	DI,DICT_DATA_BUFFER
	ADD	DI,AX
	MOV	BX,0A0DH
	MOV	[DI],BX
	
	JMP	READOK
READ_FILE_ERROR:
	LEA	DX,MSG_READ_ERROR	;读取文件错误处理
	MOV	AH,09H
	INT 21H
	CALL	RETURN
READOK:	
	RET
READ_FILE	ENDP
;******************************************************
SCAN_FILE	PROC	NEAR		;在文件中查找此单词的位置,地址在DI中

	LEA	DI,DICT_DATA_BUFFER
NEXT:
	MOV	LEN_EQUAL,0
	LEA	SI,INSERT_WORD
	CALL	DICT_NEXT_WORD
	CALL	SET_SMALL_TO_CX		;用最小的长度作为计数器
	PUSH	DI
	REPE	CMPSB			;相等时继续比较
	POP	DI
	JE	FIND_WORD
	JS	TOINSERT_WORD
GOON:
	ADD	DI,DICT_WORD_LEN
	INC	DI
	INC	DI
	JMP	NEXT
FIND_WORD:
	CMP	LEN_EQUAL,0		;长度相等才开能为同一单词
	JE	GOON
	CALL	FIND_WORD_DICT		;调用找到单词处理子程序
TOINSERT_WORD:
	CALL	INSERT_WORD_DICT	;调用插入单词处理子程序
	
	RET
SCAN_FILE	ENDP
;******************************************************
SET_SMALL_TO_CX	PROC	NEAR
	MOV	AX,DICT_WORD_LEN	;设置较短的到CX,作为比较次数
	MOV	BX,INSERT_WORD_LEN
	CMP	AX,BX
	JE	WORD_LEN_EQUAL
	JB	SHORTER
	MOV	CX,BX
	JMP	SETOK
WORD_LEN_EQUAL:
	MOV	LEN_EQUAL,1		;保存两个单词长度是否相等
SHORTER:
	MOV	CX,AX
SETOK:
	RET
SET_SMALL_TO_CX	ENDP
;*************************;从词典中跳到下个单词并取得其长度******************************
DICT_NEXT_WORD	PROC	NEAR	;传过来DI的值
	PUSH	DI			
	INC	LINE_NUM
;-----------
	MOV	BX,OFFSET DICT_DATA_BUFFER
	ADD	BX,DICT_DATA_LEN
	CMP	DI,BX
	JAE	REACH_END
;-------------	
	MOV	AL,0AH
	MOV	BX,DI
	MOV	CX,64H
	REPNZ	SCASB			;查找到下个单词的开始

	SUB	DI,BX
	SUB	DI,2
	MOV	DICT_WORD_LEN,DI
;------------
	JMP	DICTOK
REACH_END:
	;POP	DI
	MOV	AX,0A0DH	;末端处理
	MOV	[DI-2],AX
	LEA	SI,INSERT_WORD
	MOV	CX,INSERT_WORD_LEN
	REP	MOVSB
	POP	DI
	LEA	DX,MSG_INSERT_OK
	MOV	AH,09H
	INT 21H
	MOV	AX,LINE_NUM
	CALL	DEAL_NUM	
;-------------------------
	MOV	AX,INSERT_WORD_LEN
	ADD	DICT_DATA_LEN,AX
	ADD	DICT_DATA_LEN,2
	CALL	SAVE_FILE			;将缓冲区的内容保存到文件中
	CALL	DISP_SOME_WORD
	CALL	MAIN
DICTOK:
;------------	
	POP	DI	
	RET
DICT_NEXT_WORD	ENDP
;************************插入此单词*****************
INSERT_WORD_DICT	PROC	NEAR
	PUSH	DI	
;----------------------------
	LEA	SI,DICT_DATA_BUFFER
	ADD	SI,DICT_DATA_LEN
	
	MOV	CX,SI
	SUB	CX,DI
	INC	CX
	MOV	DI,SI
	ADD	DI,INSERT_WORD_LEN
	ADD	DI,2		;0DH,0AH
	STD
	REP	MOVSB
;-------------------------
	POP	DI
	CLD
	LEA	SI,INSERT_WORD
	MOV	CX,INSERT_WORD_LEN
	REP	MOVSB
	MOV	AX,0A0DH
	MOV	[DI],AX
;-------------------------
	SUB	DI,INSERT_WORD_LEN
	MOV	BX,OFFSET DICT_DATA_BUFFER	;判断DI是否到了最左端
	CMP	DI,BX			
	JE	INSERTOK
	SUB	DI,2
INSERTOK:
	LEA	DX,MSG_INSERT_OK
	MOV	AH,09H
	INT 21H
	MOV	AX,LINE_NUM
	CALL	DEAL_NUM	
;-------------------------
	MOV	AX,INSERT_WORD_LEN
	ADD	AX,2
	ADD	DICT_DATA_LEN,AX		
	CALL	SAVE_FILE			;将缓冲区的内容保存到文件中
	CALL	DISP_SOME_WORD
	CALL	MAIN
	RET
INSERT_WORD_DICT	ENDP
;******************************************************
FIND_WORD_DICT	PROC	NEAR		;找到单词处理程序
	LEA	DX,MSG_FIND_WORD
	MOV	AH,09H
	INT 21H
	MOV	AX,LINE_NUM
	CALL	DEAL_NUM
	
	CALL	DISP_SOME_WORD
	CALL	MAIN	
	RET
FIND_WORD_DICT	ENDP
;******************************关闭文件****************
CLOSE_FILE	PROC	NEAR
	MOV	AH,3EH
	MOV	BX,DICT_FILE_HANDLE
	INT 21H
	RET
CLOSE_FILE	ENDP
;******************************保存文件******************
SAVE_FILE	PROC	NEAR
	CALL	OPEN_FILE

	MOV	DX,OFFSET MSG_SAVE_OK
	MOV	AH,09H
	INT 21H
	
	MOV	AH,40H
	LEA	DX,DICT_DATA_BUFFER
	MOV	CX,DICT_DATA_LEN
	MOV	BX,DICT_FILE_HANDLE
	INT 21H

	CALL	CLOSE_FILE
	RET
SAVE_FILE	ENDP
;*******************************显示找到的单词位置之后的N个单词****************
DISP_SOME_WORD	PROC	NEAR
	LEA	DX,MSG_DISP_WORD
	MOV	AH,09H
	INT 21H
	
	MOV	CX,100H
NEXT:
	MOV	DL,[DI]
	MOV	AH,02H
	INT 21H
	INC	DI
	LOOP	NEXT
DISPOK:	
	RET
DISP_SOME_WORD	ENDP
;********************************将16进制转化为10进制并输出**********
DEAL_NUM	PROC	NEAR
	PUSH	DI
	MOV     CX,5
	
        MOV     BX,10
        MOV     DI,OFFSET LINE_BUFFER+4	;从后往前保存

LP4:    XOR     DX,DX			;将DX清零 
        DIV     BX
        OR      DL,30H			;也可用ADD DL,30H	
        MOV     BYTE PTR [DI],DL	;将16进制的数转换到ASCII中对应的数,0的ASCII码为 30H (48D)
        CMP	AX,0
        JZ	PRINT			;当商为0时,直接去打印,可不打印高位的0.
        DEC     DI
        LOOP    LP4
PRINT:
        MOV     DX,DI			;从DI开始打印,因为RESULT不一定够5位
        MOV     AH,9
        INT     21H			;调用DOS的21号中断的9号功能,将DB输出

	POP	DI
        RET
DEAL_NUM	ENDP
;***************************************返回DOS*********
RETURN	PROC	NEAR	
	MOV	AX,4C00H
	INT 21H	
	RET
RETURN	ENDP
;********************************************************
CODE	ENDS
	END	MAIN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -