для ввода имени файла. Если ввод пустой, то происходит вызов
G10PROC для завершения программы.
C10OPEN Создает для файла элемент в директории, устанавливает размер
записей - 32 (шест.20) и инициализирует адрес буфера DTA для
DOS.
D10PROC Выдает запрос на ввод имен, вводит имена с клавиатуры и
вызывает процедуру F10WRIT для записи вводимых имен на диск
E10DISP Управляет прокруткой и установкой курсора.
F10WRIT Записывает имена в дисковой файл.
G10CLSE Записывает маркер конца файла и закрывает файл.
X10ERR Выдает на экран сообщение об ошибке в случае не корректной
операции создания файла или записи данных.
Каждая операция записи автоматически добавляет 1 к FCBSGRC (номер
текущей записи) и шест.20 (размер записи) к FCBFLSZ (размер файла). Так
как каждая запись имеет длину 32 байта, то операция заносит в буфер 16
записей и затем записывает весь буфер в сектор диска. Ниже показано
содержимое DTA и буфера:
DTA: |текущая запись|
Буфер: |запись 00|запись 01|запись 02|...|запись 15|
Если пользователь ввел 25 имен, то счетчик записей увеличится от 1 до
25 (шест.19). Размер файла составит:
25 * 32 байта = 800 байтов или шест. 320
Операция закрытия заносит во второй сектор оставшиеся в буфере девять
записей и изменяет в оглавлении дату и размер файла. Размер записывается
байтами в переставленном порядке: 20030000. Последний буфер имеет
следующий вид:
Буфер: |запись 16|запись 17|...|запись 24|шест.1A|...|...|
Для простоты в приведенной программе создаются записи файла,
содержащие только одно поле. Записи большинства других файлов, однако,
содержит различные символьные и двоичные поля и требуют описания записи в
DTA. Если записи содержат двоичные числа, то не следует использовать
маркер конца файла (EOF), так как двоичное число может совпасть с шест.
кодом 1A.
Для того, чтобы сделать программу более гибкой, можно разрешить
пользователю указать дисковод, на котором находится или будет находиться
файл. В начале выполнения программа может выдать на экран сообщение, чтобы
пользователь ввел номер дисковода, а затем изменить первый байт блока FCB.
ПОСЛЕДОВАТЕЛЬНОЕ ЧТЕНИЕ ДИСКОВОГО ФАЙЛА
________________________________________________________________
В базовой версии DOS программа, читающая дисковый файл, содержит блок
управления файлом, который определяет файл точно так, как он был создан. В
начале программа для открытия файла использует функцию шест. OF:
MOV AH,OFH ;Открытие
LEA DX,FCBname ; файла
INT 21H ;Вызов DOS
Операция открытия начинается с поиска в оглавлении элемента с именем
и типом файла, определенными в FCB. Если такой элемент не будет найден в
оглавлении, то в регистре AL устанавливается шест.FF. Если элемент найден,
то в регистре AL устанавливается 00 и в FCB заносится действительный
размер файла, а также устанавливается номер текущего блока в 0, длина
записи в шест.80. После открытия можно заменить длину записи на другое
значение.
DTA должно содержать определение считываемой записи в соответствии с
форматом, который использовался при создании файла. Для установки адреса
DTA используется функция шест.1A (не путать с маркером конца файла EOF
шест.1A) аналогично созданию дискового файла:
MOV AH,1AH ;Установка
LEA DX,DTAname ; адреса DTA
INT 21H ;Вызов DOS
Для последовательного чтения записей с диска используется функция
шест.14:
MOV AH,14H ;Последовательное
LEA DX,FCBname ; чтение записей
INT 21H ;Вызов DOS
Чтение записи с диска по адресу DTA осуществляется на основе
информации в блоке FCB. Операция чтения устанавливает в регистре AL
следующие коды возврата:
00 Успешное чтение.
01 Конец файла, данные не прочитаны.
02 В DTA нет места для чтения одной записи.
03 Конец файла, прочитана частичная запись, заполненная нулями.
Первая операция чтения заносит содержимое всего сектора в буфер DOS.
Затем операция определяет из блока FCB размер записи и пересылает первую
запись из буфера в DTA. После дующие операции чтения пересылают остальные
записи (если имеются) пока буфер не будет исчерпан. После этого операция
чтения определяет адрес следующего сектора и заносит его содержимое в
буфер.
После успешной операции чтения в блоке FCB автоматически
увеличивается номер текущей записи на 1. Завершение последовательного
чтения определяется программой по маркеру конца файла (EOF), для чего в
программе имеется соответствующая проверка. Так как оглавление при чтении
файла не изменяется, то обычно нет необходимости закрывать файл после
завершения чтения. Исключение составляют программы, которые открывают и
читают несколько файлов одновременно. Такие программы должны закрывать
файлы, так как DOS ограничивает число одновременно открытых файлов.
ПРОГРАММА: ИСПОЛЬЗОВАНИЕ FCB ДЛЯ ЧТЕНИЯ ДИСКОВОГО ФАЙЛА
________________________________________________________________
__________________________________________________________________________
TITLE FCBREAD (EXE) Чтение записей созданных в CREATDSK
; -------------------------------------------------------
STACKSG SEGMENT PARA STACK 'Stack'
DW 80 DUP(?)
STACKSG ENDS
;--------------------------------------------------------
DATASG SEGMENT PARA 'Data'
FCBREC LABEL BYTE ;FCB для файла
FCBDRIV DB 04 ; дисковод D
FCBNAME DB 'NAMEFILE' ; имя файла
FCBEXT DB 'DAT' ; тип файла
FCBBLK DW 0000 ; номер текущего блока
FCBRCSZ DW 0000 ; длина логической записи
DD ? ; размер файла (DOS)
DW ? ; дата (DOS)
DT ? ; зарезервировано (DOS)
FCBSQRC DB 00 ; текущий номер записи
DD ? ; относительный номер
RECLEN EQU 32 ;Длина записи
NAMEFLD DB RECLEN DUP(' '), 13, 10, '$'
ENDCDE DB 00
OPENMSG DB '*** Open error ***', '$'
READMSG DB '*** Read error ***', '$'
ROW DB 00
DATASG ENDS
;--------------------------------------------------------
CODESG SEGMENT PARA 'Code'
BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATASG
MOV DS,AX
MOV ES,AX
MOV AX,0600H
CALL Q10SCR ;Очистить экран
CALL Q20CURS ;Установить курсор
CALL E10OPEN ;Открыть файл,
; установить DTA
CMP ENDCDE,00 ;Открытие без ошибок?
JNZ A90 ; нет - завершить
A20LOOP:
CALL F10READ ;Прочитать запись
CMP ENDCDE,00 ;Чтение без ошибок?
JNZ A90 ; нет - выйти
CALL G10DISP ;Выдать имя на экран
JMP A20LOOP ;Продолжить
A90: RET ;Завершить
BEGIN ENDP
; Открытие файла на диске:
; -----------------------
E10OPEN PROC NEAR
LEA X,FCBREC
MOV AH,0FH ;Функция открытия
INT 21H
CMP AL,00 ;Файл найден?
JNZ E20 ; нет - ошибка
MOV FCBRCSZ,RECLEN ;Длина записи (EQU)
MOV AH,1AH
LEA DX,NAMEFLD ;Адрес DTA
INT 21H
RET
E20:
MOV ENDCDE,01 ;Сообщение об ошибке
LEA DX,OPENMSG
CALL X10ERROR
RET
E10OPEN ENDP
; Чтение дисковой записи:
; ----------------------
F10READ PROC NEAR
MOV AH,14H ;Функция чтения
LEA DX,FCBREC
INT 21H
CMP NAMEFLD,1AH ;Считан маркер EOF?
JNE F20 ; нет
MOV ENDCDE,01 ; да
JMP F90
F20:
CMP AL,00 ;Чтение без ошибок?
JZ F90 ; да - выйти
MOV ENDCDE,01 ;Нет:
CMP AL,01 ;Конец файла?
JZ F90 ; да - выйти,
LEA DX,READMSG ; нет - значит
CALL X10ERR ; ошибка чтения
F90:
RET
F10READ ENDP
; Вывод записи на экран:
; ---------------------
G10DISP PROC NEAR
MOV AH,09 ;Функция вывода на экран
LEA DX,NAMEFLD
INT 21H
CMP ROW,20 ;Последняя строка экрана?
JAE G30 ; нет...
INC ROW ; да - увеличить строку
JMP G90
G30:
MOV AX,0601H
CALL Q10SCR ; прокрутить
CALL Q20CURS ; установить курсор
G90: RET
G10DISP ENDP
; Прокрутка (скроллинг) экрана:
; ----------------------------
Q10SCR PROC NEAR ;AX уже установлен
MOV BH,1EH ;Установить цвет
MOV CX,0000
MOV DX,184FH ;Функция прокрутки
INT 10H
RET
Q1OSCR ENDP
; Установка курсора:
; -----------------
Q20CURS PROC NEAR
MOV AH,02
MOV BH,00
MOV DH,ROW
MOV DL,00
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке на диске:
; ----------------------------------
X10ERR PROC NEAR
MOV AH,09 ;DX содержит адрес
INT 21H ; сообщения
RET
X10ERR ENDP
CODESG ENDS
END BEGIN
__________________________________________________________________________
Рис.16.2. Чтение дискового файла
На рис.16.2 приведена программа, которая выполняет чтение файла,
созданного предыдущей программой, и вывод на экран имен из записей файла.
Обе программы содержат идентичные блоки FCB, хотя, имена полей FCB могут
быть различны. Содержимое полей имени и типа файла должны быть одинаковы.
Программа содержит следующие процедуры:
BEGIN Инициализирует сегментны регистра, вызывает процедуру E10OPEN
для открытия файла и установки DTA и вызывает F10READ для чтения
записей. Если считан маркер конца файла, то программа
завершается, если нет, то вызывается процедура G10DISP.
E10OPEN Открывает файл, устанавливает значение размера и записей,
равное 32 (шест.20), и инициализирует адрес DTA.
F10READ Выполняет последовательное чтение записей. Операция чтения
автоматически увеличивает номер текущей записи в блоке FCB.
G10DISP Выводит на экран содержимое прочитанной записи.
X10ERR Выводит на экран сообщение об ошибке в случае некорректной
операции открытия или чтения.
Операция открытия выполняет поиск имени и типа файла в оглавлении.
Если необходимый элемент оглавления найден, то автоматически в блок FCB
заносятся размер файла, дата и длина записей. Первая операция чтения
записи с номером 00 получает доступ к диску и считывает весь сектор (16
записей) в буфер. После этого первая запись заносится в DTA, а номер
текущей записи в FCB увеличивается с 00 до 01: