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