例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,我们不难掌握记录文件的读写方法。有兴趣的读者,还可以利用文件指针的定位来指定读写某个具体的记录。