首先在一个文本文件中写入一些电话号码,为了读取的方便,指定它们有固定的格式,并且以dollar串结束符结束,便于用3FH号功能读取文件和09H号功能输出。
注意,虽然3FH号功能读入的东西,在输出时到串结束符就没有了,这只是因为09H号功能的结束时在串结束符dollar符,在3FH号功能的使用时还是要决策好要读入的字符数目。
另外两个新的知识是,3DH号功能打开文件,以及用42H号功能移动文件指针(有至少三种移动方式,根据AL的值来指定)。
DATAS SEGMENT
WJ DB 'D:\tel.txt',00H ;文件路径
HAND DW ? ;文件代号
LS2 DB 20 DUP(?),'$' ;小临时空间
NAMEN DB 7 ;表示最多存7个字符
DB ? ;预留!保存实际存的字符数
DB 6 DUP (?) ;接收输入串
DB '$','$' ;这里完全是我的无能之举!
NOSTR DB 'NOT FIND','$' ;找不到
PIAN DW 00H ;偏移量
TELNUM DB 4 ;电话号码数量
HH DB 0AH,0DH,'$' ;换行回车
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
;--------输入名字----------
LEA DX,NAMEN
MOV AH,0AH ;0A号功能接受输入到缓冲区
;DS:DX=缓冲区首地址
;(DS:DX)保存缓冲区最大字符数
;(DS:DX+1)保存实际输入字符数
INT 21H
LEA DX,HH
MOV AH,09H
INT 21H
MOV BH,0
MOV BL,DS:NAMEN[1] ;int i=名字的字符数
BUQUAN: ;补全
MOV DL,'-' ;补全用的字符
MOV DS:NAMEN[BX+2],DL ;从+2位置开始字符补全
ADD BX,1 ;游标+1右移
CMP BX,7 ;到7说明结束了
JB BUQUAN ;不到7要继续补全
LEA DX,NAMEN[2]
MOV AH,09H
INT 21H
;换行
LEA DX,HH
MOV AH,09H
INT 21H
;-------打开文件-----------
MOV AH,3DH ;打开文件的操作
MOV AL,00 ;只读
LEA DX,WJ ;把文件路径的地址给DX
INT 21H ;干活
JC ERROR ;出错跳转
;执行到这里后,文件代号将在AX里
MOV HAND,AX ;存进HAND里
MYXUN: ;主循环
;-------移动文件指针-------
MOV AH,42H ;移动文件指针
MOV CX,0
MOV DX,PIAN ;CX:DX是偏移量
ADD PIAN,22 ;偏移量每次加22(算上回车换行!)
MOV AL,0 ;移动方式:从头开始算
MOV BX,HAND ;文件代号给BX
INT 21H
;---------读取-------------
MOV AH,3FH ;读文件的操作
MOV BX,HAND ;文件代号给BX
MOV CX,20 ;要读的长度给CX,注意要正好!
LEA DX,LS2 ;要读到的位置给DX
INT 21H
JC ERROR ;错误跳转
;执行好读后,实际读的字节数在AX里
;---------比较名字---------
MOV BX,0 ;比较用的游标初始化
MOV CX,7 ;比较7个字符
CMPNAME:
MOV DL,DS:LS2[12+BX]
CMP DS:NAMEN[BX+2],DL ;逐个字符作比较
JNE THISNO ;不同时跳转
INC BX ;游标增加
LOOP CMPNAME ;相同时继续循环比较
;如果运行到这句,说明比较结果是一致
JMP SHUCHU ;一致则跳转到输出结束
THISNO: ;到这里说明本次比较是不一致的
DEC TELNUM ;每次TELNUM-1
CMP TELNUM,0 ;和0比较一下
JE NONE ;到0了说明没找到
JMP MYXUN ;否则继续主循环
SHUCHU:
;---------输出-------------
LEA DX,HH
MOV AH,09H
INT 21H
LEA DX,LS2 ;串地址给DX
MOV AH,09H ;显示字符串的操作
INT 21H
ERROR: ;直接结束
MOV AH,4CH
INT 21H
NONE: ;没找到
LEA DX,HH
MOV AH,09H
INT 21H
LEA DX,NOSTR
MOV AH,09H
INT 21H
INT 21H
JMP ERROR
CODES ENDS
END START
在读入名字后,用减号对名字进行补全,补全到7位,这样就可以和文件中的记录保持格式上的一致性,并且每次只要把CX置7(补全之后总是7位的名字),就能很方便地一位一位地作字符比较。
这样做的另一个好处是,如果一个名字是另一个名字的前缀串,如TOM于TOMMY是前缀串,也不会发生错误。例如在这个文件中TOM是TOMMY的前缀串,甚至还在TOMMY的前面,仍然能判断两者并不相同,而只作名字长度的循环是不能避免这个问题的。