ITEEDU

例10.12 编写一个程序显示由例10.11建立的记录文件students.dat中的学生信息。 

解:


.MODEL SMALL,C

     student  STRUCT

id DW ?

sname DB 10 DUP(?)

age DB ?

     student  ENDS

.DATA

fname DB "Students.dat",0

id1 DB "Id:", 4 dup(?), 0dh, 0ah, "$"

name1 DB "Name:", 10 dup(' '), 0dh, 0ah, "$"

age1 DB "Age:", 2 dup(?), 0dh, 0ah, "$"

msg1 DB "Fail to open file$"

peason student <>

.CODE

     DispMsg  PROC      USES AX DX, Msg:PTR BYTE            ;显示字符串Msg

…… ;参见例10.7

     DispMsg  ENDP

;程序功能:把数据Data转换成长度为Len的字符串; 

;入口参数:待转换数据Data,转换成字符串的长度为Len,存放字符串的首地址为PStr; 

;出口参数:读入信息(字符串)存放缓冲区buff中。 

      GetStr  PROC      USES AX CX DX DI, Data:WORD, Len:WORD, PStr:PTR BYTE

              MOV       CX, Len

              MOV       DI, PStr

              MOV       AL, ' '

              REP       STOSB       ;把存放字符串的缓冲区填充为空格

              MOV       DI, PStr

              ADD       DI, Len

              DEC       DI          ;确定最后一个字符在缓冲区中的位置

              MOV       AX, Data

              MOV       CX, 10

.REPEAT

              XOR       DX, DX

              IDIV      CX?         ;除10,从低位向高位求得每一位

              ADD       DL, '0'     ;把余数转变成字符,然后存放目标单元

              MOV       [DI], DL

              DEC       DI

.UNTIL AX==0

              RET

      GetStr  ENDP

.STARTUP

              MOV       AX, DS

              MOV       ES, AX

LEA?DX, fname

              MOV       AL, 0H

              MOV       AH, 3DH

              INT       21H         ;以“只读”方式打开指定的文件

.IF CARRY? ;若创建失败,则显示失败信息 

INVOKE DispMsg, ADDR msg1

              JMP over

.ENDIF

              MOV       BX, AX      ;把句柄存入BX,为后面使用作准备

      again:

              MOV       CX, SIZE peason

              LEA       DX, peason

              MOV       AH, 3FH

              INT       21H         ;从文件中读出一个记录

.IF CARRY? || AX==0 ;若读记录出错或遇到文件尾,结束 

              JMP       close

.ENDIF

              INVOKE    GetStr, peason.id, 4, ADDR Id1+3    ;把“学号”转换成字符串

              INVOKE    DispMsg, ADDR Id1       ;显示“学号”字符串

              MOV       CX, 10

              LEA       SI, peason.sname

              LEA       DI, Name1+5

              REP       MOVSB?      ;把“姓名”转移到显示区

              INVOKE    DispMsg, ADDR Name1     ;显示“姓名”字符串

              INVOKE    Getstr, peason.age, 2, ADDR Age1+4  ;把“年龄”转换成字符串

              INVOKE    Dispmsg, ADDR Age1      ;显示“年龄”字符串

              JMP       again

      close:

              MOV       AH, 3EH

              INT       21H         ;关闭当前打开的文件

       over:

.EXIT         0

              END
从例10.11和10.12,我们不难掌握记录文件的读写方法。有兴趣的读者,还可以利用文件指针的定位来指定读写某个具体的记录。