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