【汇编学习笔记】4:电话号查找(文件指针读取文件)

首先在一个文本文件中写入一些电话号码,为了读取的方便,指定它们有固定的格式,并且以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的前面,仍然能判断两者并不相同,而只作名字长度的循环是不能避免这个问题的。
这里写图片描述
这里写图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值