--------------------------
После завершения записи файла необходимо установить файловый номер в
регистр BX и, используя функцию DOS шест.3E, закрыть файл. Эта операция
записывает все оставшиеся еще данные из буфера на диск и корректирует
оглавление и таблицу FAT.
MOV AH,3EH ;Запрос на закрытие файла
MOV BX,HANDLE1 ;Файловый номер
INT 21H ;Вызов DOS
В случае ошибки в регистре AX устанавливается код 06 (неправильный
файловый номер).
ПРОГРАММА:ИСПОЛЬЗОВАНИЕ ФАЙЛОВОГО НОМЕРА ДЛЯ СОЗДАНИЯ ФАЙЛА.
________________________________________________________________
__________________________________________________________________________
page 60,132
TTILE HANCREAT (EXE) Создание файла на диске
; -----------------------------------------------------
STACKSG SEGMENT PARA STACK 'Stack'
DW 80 DUP(?)
STACKSG ENDS
; -----------------------------------------------------
DATASG SEGMENT PARA 'Data'
NAMEPAR LABEL BYTE ;Список параметров:
MAXLEN DB 30 ;
NAMELEN DB ? ;
NAMEREC DB 30 DUP(' '), 0DH, 0AH ; введенное имя, CR/LF для записи
ERRCDE DB 00
HANDLE DW ?
PATHNAM DB 'D:\NAMEFILE.DAT',0
PROMPT DB 'Name? '
ROW DB 01
OPNMSG DB '*** Open error ***', 0DH, 0AH
WRTMSG DB '*** Write error ***', 0DH, 0AH
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 C10CREA ;Создание файла, установка DTA
CMP ERRCDE,00 ;Ошибка при создании?
JZ A20LOOP ; да - продолжить,
RET ; нет - вернуться в DOS
A20LOOP:
CALL D10PROC
CMP NAMELEN,00 ;Конец ввода?
JNE A20LOOP ; нет - продолжить,
CALL G10CLSE ; да - закрыть файл
RET ; и выйти в DOS
BEGIN ENDP
; Создание файла на диске:
; -----------------------
C10CREA PROC NEAR
MOV AH,3CH ;Функция создания файла
MOV CX,00 ;Нормальный атрибут
LEA CX,PATHNAM
INT 21H
JC C20 ;Есть ошибка?
MOV HANDLE,AX ; нет - запомнить номер,
RET
C20: ; да -
LEA DX,OPNMSG ; выдать сообщение
CALL X10ERR ; об ошибке
RET
C10CREA ENDP
; Ввод с клавиатуры:
; -----------------
D10PROC PROC NEAR
MOV AH,40H ;Функция вывода на экран
MOV BX,01 ;Номер (Handle)
MOV CX,06 ;Длина текста запроса
LEA DX,PROMPT ;Выдать запрос
INT 21H
MOV AH,0AH ;Функция ввода с клавиатуры
LEA DX,NAMEPAR ;Список параметров
INT 21H
CMP NAMELEN,00 ;Имя введено?
JNE D20 ; да - обойти
RET ; нет - выйти
D20:
MOV AL,20H ;Пробел для заполнения
SUB CH,CH
MOV CL,NAMELEN ;Длина
LEA DI,NAMEREC ;
ADD DI,CX ;Адрес + длина
NEG CX ;Вычислить
ADD CX,30 ; оставшуюся длину
REP STOSB ;Заполнить пробелом
D90:
CALL F10WRIT ;Запись на диск
CALL E10SCRL ;Проверка на скроллинг
RET
D10PROC ENDP
; Проверка на скроллинг:
; ---------------------
E10SCRL PROC NEAR
CMP ROW,18 ;Последняя строка экрана
JAE E10 ; да - обойти,
INC ROW ; нет - увеличить строку
JMP E10
E10:
MOV AX,0601H ;Продвинуть на одну строку
CALL Q10SCR
E90: CALL Q20CURS ;Установка курсора
RET
E10SCRL ENDP
; Запись на диск:
; --------------
F10WRIT PROC NEAR
MOV AH,40H ;Функция записи на диск
MOV BX,HANDLE
MOV CX,32 ;30 для имени + 2 для CR/LF
LEA DX,NAMEREC
INT 21H
JNC F20 ;Ошибка записи?
LEA DX,WRTMSG ; да -
CALL X10ERR ; выдать предупреждение
MOV NAMELEN,00
F20:
RET
F10WRIT ENDP
; Закрытие файла на диске:
; -----------------------
G10CLSE PROC NEAR
MOV NAMEREC,1AH ;Маркер конца записи (EOF)
CALL F10WRIT
MOV AH,3EH ;Функция закрытия
MOV BX,HANDLE
INT 21H
RET
G10CLSE ENDP
; Прокрутка (скроллинг) экрана:
; ----------------------------
Q10SCR PROC NEAR ;в AX - адрес элемента
MOV BH,1EH ;Цвет - желтый на синем
MOV CX,0000
MOV DX,184FH
INT 10H ;Скроллинг
RET
Q10SCR ENDP
; Установка курсора:
; -----------------
Q20CURS PROC NEAR
MOV AH,02
MOV BH,00
MOV DH,ROW ;Установить курсор
MOV DL,00
INT 10H
RET
Q20CURS ENDP
; Вывод сообщения об ошибке:
; -------------------------
X10ERR PROC NEAR ;DX содержит
MOV AH,40H ; адрес сообщения
MOV BX,01
MOV CX,21 ;Длина сообщения
INT 21H
MOV ERRCDE,01 ;Установить код ошибки
RET
X10ERR ENDP
CODESG ENDS
END BEGIN
__________________________________________________________________________
Рис.17.2. Использование файлового номера для создания файла.
Программа, приведенная на рис.17.2, создает файл по имени, которое
вводится пользователем с клавиатуры. В программе имеются следующие
основные процедуры:
C10CREA Использует функцию шест.3C для создания файла и сохраняет
файловый номер в элементе данных по имени HANDLE.
D10PROC Принимает ввод с клавиатуры и очищает пробелом байты от конца
введенного имени до конца области ввода.
F10WRIT Записывает файл, используя функцию шест.40.
G10CLSE В завершении обработки, используя функцию шест.3E,закрывает файл
для того, чтобы создать правильный элемент оглавления.
Область ввода имеет длину 30 байтов и завершается двумя байтами:
возврат каретки (шест.0DH) и конец строки (шест.0AH). Таким образом общая
длина области ввода - 32 байта. Программа переносит на диск 32-x байтовые
записи, как записи фиксированной длины. Можно опустить байты "возврат
каретки" и "конец строки", но включить их, если потребуется сортировка
файла. Программа DOS SORT требует наличия этих байтов для индикации конца
записей. Для нашего примера команда SORT может выглядеть следующим
образом:
SORT B:NAMEFILE.SRT
В результате выполнения данной команды записи из файла NAMEFILE.DAT в
возрастающей последовательности будут помещены в файл NAMEFILE.SRT.
Программа, приведенная на рис.17.3 выполняет чтение записей из файла
NAMEFILE.SRT и вывод их на экран. Обратите внимание на два момента: 1)
Символы возврат каретки и конец строки включены в конце каждой записи
только для выполнения сортировки и в других случаях могут быть опущены. 2)
Записи могут иметь переменную длину (по длине вводимых с клавиатуры имен);
эта особенность включает некоторое дополнительное программирование, как
это будет показано на рис.17.4.
ЧТЕНИЕ ДИСКОВОГО ФАЙЛА
________________________________________________________________
В следующих разделах раскрыты требования для открытия и чтения
дисковых файлов в расширенной версии DOS.
Открытие файла: шест.3D
-------------------------
Если в программе требуется прочитать дисковый файл, то прежде
необходимо открыть его, используя функцию шест.3D. Эта операция проверяет
правильность имени файла и его наличие на диске. При открытии регистр DX
должен содержать адрес необходимой ASCIIZ-строки, а регистр AL - код
доступа:
0 Открыть файл только для ввода
1 Открыть файл только для вывода
2 Открыть файл для ввода и вывода
Остальные биты регистра AL используются для разделения файлов DOS версии
3.0 и старше (см.техническое руководство по DOS). Обратите внимание, что
для записи файла используется функция создания (шест.3C), но не функция
открытия файла. Ниже приведен пример открытия файла для чтения:
MOV AH,3DH ;Запрос на открытие
MOV AL,00 ;Только чтение
LEA DX,PATHNM1 ;Строка в формате ASCIIZ
INT 21H ;Вызов DOS
JC error4 ;Выход по ошибке
MOV HANDLE2,AX ;Сохранение номера в DW
Если файл с необходимым именем существует, то операция открытия
устанавливает длину записи равной 1, принимает существующий атрибут,
сбрасывает флаг CF и заносит файловый номер в регистр AX. Файловый номер
используется в дальнейшем для всех последующих операций.
Если файл отсутствует, то операция устанавливает флаг CF и заносит в
регистр AX код ошибки: 02, 04, 05 или 12 (см. рис.17.1). Не забывайте
проверять флаг CF. При успешном создании файла система может установить в
регистре AX файловый номер 0005, что легко можно спутать с кодом ошибки 05
(нет доступа).
Чтение файла: Шест.3F
-----------------------
Для чтения записей файла используется функция DOS шест.3F. При этом
необходимо установить в регистре BX файловый номер, в регистре CX - число
байтов и в регистре DX - адрес области ввода. В следующем примере
происходит считывание 512-байтовой записи:
HANDLE2 DW ?
INPREC DB 512 DUP (' ')
MOV AH,3FH ;Запрос на чтение
MOV BX,HANDLE2 ;Файловый номер
MOV CX,512 ;Длина записи
LEA DX,INPREC ;Адрес области ввода
INT 21H ;Вызов DOS
JC error5 ;Проверка на ошибку
CMP AX,00 ;Прочитано 0 байтов?
JE endfile
Правильно выполненная операция считывает запись в память, сбрасывает
флаг CF и устанавливает в регистре AX число действительно прочитанных
байтов. Нулевое значение в регистре AX обозначает попытку чтения после
конца файла. Ошибочная операция устанавливает флаг CF и возвращает в
регистре AX код ошибки 05 (нет доступа) или 06 (ошибка файлового номера).
Так как DOS ограничивает число одновременно открытых файлов, то
программа, успешно отработавшая с несколькими файлами, должна закрывать
их.
ПРОГРАММА: ИСПОЛЬЗОВАНИЕ ФАЙЛОВОГО НОМЕРА ДЛЯ ЧТЕНИЯ ФАЙЛА
________________________________________________________________