Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции СП.doc
Скачиваний:
9
Добавлен:
01.03.2025
Размер:
1.98 Mб
Скачать

Лекция 2.6. Работа с файлами, каталогами и дисками под управлением ms-dos

В основе файловой системы MS DOS лежит древовидная структура каталогов. Корень этой структуры представляет собой совокупность ограниченного числа дескрипторов, описывающих файлы и каталоги (подкаталоги) следующего уровня. Подкаталог представляет собой файл особого типа, который содержит дескрипторы файлов и подкаталогов очередного нижележащего уровня. В отличие от корневого каталога количество дескрипторов в подкаталоге не ограничено и определяется только размером диска. Дескриптор представляет собой экземпляр структуры размером 32 байта. Поля этой структуры содержат различную информацию о файле: идентификатор файла и его характеристики — дата и время создания (модификации), номер начального кластера, длина файла и его атрибуты.

Для использования файла в программе необходимо выполнить следующие операции:

  • создание нового файла;

  • открытие существующего файла;

  • запись/чтение в/из файл(а);

  • закрытие файла.

Операционная система MS DOS поддерживает эти операции с помощью набора функций прерывания 21h. Кроме этих функций данное прерывание содержит функции для работы с каталогами:

  • создать каталог;

  • удалить каталог;

  • сменить каталог.

Существует также ряд других функций для работы с файловой системой, в том числе для поиска файлов и получения информации о них.

Создание, открытие, закрытие и удаление файла

Прежде чем использовать файл в программе, его необходимо открыть с помощью функции 3dh прерывания 21h. Если файл не существует, то перед открытием его нужно создать. Оба эти действия выполняются одной из следующих функций: 3ch, 5bh, 5ah, 6ch.

Создание файла с усечением существующего до нулевой длины

Вход: АН = 3Ch; CX = атрибуты файла (значения битов: 0=1 — только чтение; 1= 1 — скрытый файл; 2=1 — системный файл; 3=0 — игнорируется; 4=0 — зарезервирован (каталог), должен быть равен 0; 5 — бит архивации; 6= 0 — резерв; 7=1 — общий файл в системе Novell Netware; 8...15=0 — резерв); DS:DX — ASCIZ-имя файла.

Выход: CF=O — АХ = дескриптор файла; CF=1 — АХ = код ошибки (3 — нет такого пути; 4 — нет свободного дескриптора файла; 5 — доступ отказан).

хоr сх,сх ;атрибуты файла - обычный файл

lds dx,point_fname ; формируем указатель на имя файла

mov ah,3ch ;номер функции DOS

int 21h ;открываем файл

jc exit ;переход, в случае ошибки

ml: ;действия при успешном открытии файла:

mov handle,ax ;сохраним дескриптор файла

Открытие или создание файла с расширенными возможностями

Функция 6Ch появилась в последних версиях MS DOS (DOS 4.0+). С ее появлением устраняется необходимость отслеживать существование создаваемого файла. Для корректной работы достаточно задать нужные значения в соответствующих регистрах. Анализ возможных значений показывает, что данная функция фактически заменяет существовавшие до этого функции создания и открытия файлов. Вход: АХ = 6C00h; BL = флаги — режим открытия (значения битов: 7 — наследование; 4-6 — режим разделения; 3=0 — резерв; 0-2 — режим доступа); ВН = флаги (значения битов: 6=0 — использовать стандартную для MS DOS буферизацию; 6=1 — отменить стандартную для MS DOS буферизацию; 5=0 — использовать обычный обработчик ошибок (int 24h); 5=1 — не использовать обычный обработчик ошибок (int 24h), для выяснения причины ошибки использовать функцию 59h int 21h); CX = атрибуты создаваемого (и только) файла; DL = действия, если файл существует или не существует (значения бит: 0-3 — действие, если файл существует (0000 — вернуть ошибку; 0001 — открыть файл; 0002 — открыть файл без сохранения существующего); 4-7 — действие, если файл не существует (0000 — вернуть ошибку; 0001 — открыть файл; 0002 — создать и открыть файл); DH = 00h — резерв; DS:SI — адрес строки с ASCIZ-именем файла.

Выход: CF = 0 — успешное выполнение функции: АХ = дескриптор файла, СХ = состояние (0 — файл открыт; 1 — файл создан и открыт; 2 — файл открыт без сохранения содержимого существующего файла); CF = 1 — АХ = код ошибки.

Следующий фрагмент программы показывает вариант применения функции 6Ch.

prg07_04.asm - программа демонстрации открытия или создания файла :с расширенными возможностями в текущем каталоге функцией 6ch.

.data

handle dw 0 ;дескриптор файла

filename db 'my_file.txt', 0

point_fname dd filename

.code

хоr сх,сх ;атрибуты файла - обычный файл

mov bx,2 ;режим доступа обычный - доступ для чтения-записи

mov dx,1 ;если файл существует, то открыть его. в обратном случае

;вернуть ошибку (для эксперимента)

lds si,point_fname ;формируем указатель на имя файла

mov ah,6ch ;номер функции DOS

int 21h ;открываем файл

jnc ml ;если файл существовал, то переход

mov dx.10h ;открыть файл

mov ah,6ch ;номер функции DOS

int 21h ;открываем файл

jc exit ;переход в случае ошибки

ml: ;действия при успешном открытии файла:

mov handle,ах ;сохраним дескриптор файла

Закрытие файла

В конце работы с файлом его нужно закрыть. Но это действие не является обязательным, так как функция 4сп, которая завершает выполнение программы, в числе прочих действий выполняет и закрытие всех файлов. Вход: АН = 3Eh; BX = дескриптор файла, полученный при его открытии. Выход: CF = 0 — АХ = не определен; CF = 1 — АХ = код ошибки: 6 — недопустимый дескриптор.

Во время закрытия файла выполняются все незаконченные операции записи на диск в элементе каталога, соответствующего файлу, модифицируются различные поля, в том числе поля времени и даты устанавливаются в текущее время.

Установка текущей файловой позиции

Чтение-запись в файле производятся с текущей файловой позиции, на которую указывает файловый указатель. Функция 42h MS DOS предоставляет гибкие возможности как для начального, так и для текущего позиционирования файлового указателя для последующей операции ввода-вывода. Вход: АН = 42h; BX = дескриптор файла, полученный при его открытии; AL = начальное положение в файле, относительно которого производится операция чтения-записи (00h — смещение (беззнаковое значение в CX:DX) от начала файла; 01h — смещение (значение со знаком в CX:DX) от текущей позиции в файле; 02h — смещение (значение со знаком в CX:DX) от конца файла); CX:DX = смещение новой позиции в файле относительно начальной.

Выход: CF = 0 — DX:AX = значение новой позиции в байтах относительно начала файла; CF = 1 — АХ = код ошибки: 1 — неверное значение в AL; 6 — недопустимый дескриптор файла. Методы позиционирования, заданные величиной в AL, по-разному трактуют значение в паре регистров CX:DX. Метод al = 00 трактует значение в CX:DX как абсолютное. Два других метода (al = 01 и al = 02) трактуют содержимое CX:DX как значение со знаком. Необходимо быть внимательным при выполнении операции позиционирования для избегания последующих ошибок при операции чтения-записи. Так, значение в СХ:DX, позиционирующее указатель, может указывать за пределы файла. При этом выделяются два случая:

  • значение в СХ: DX указывает на позицию перед началом файла — в этом случае последующая операция чтения-записи будет выполнена с ошибкой;

  • значение в СХ:DX указывает на позицию за концом файла — в этом случае последующая операция записи приведет к расширению файла в соответствии со значением в CX:DX.

Примеры использования функции 42h приведем при рассмотрении функций чтения-записи.

Запись в файл или устройство

Запись в файл производится функцией 40h с текущей позиции файлового указателя. Вход: АН = 40h; ВХ = дескриптор файла; СХ = количество байтов для записи; DS:DX — указатель на область, из которой записываются данные. Выход: CF = 0 — АХ = число действительно записанных байтов в файл или устройство; CF = 1 — АХ = код ошибки: 5 — в доступе отказано; 6 — недопустимый дескриптор.

Если при вызове функции 40h регистр СХ равен нулю, то данные в файл не записываются и он усекается или расширяется до текущей позиции файлового указателя. Если СХ не равен нулю, то данные в файл записываются начиная с текущей позиции файлового указателя. Операция записи также продвигает файловый указатель на число действительно записанных байтов. Положение файлового указателя можно изменять явно с помощью функции 42h. Вначале приведем пример программы, выводящей данные на экран.

:prg07_08.asm - программа демонстрации вывода на экран строки функцией 40h.

.data

string db 'строка для вывода на экран функцией 40h'

len_string = $-string

point_fname dd string

..........

.code

mov bx,1 ;стандартный дескриптор – экран

mov cx,1en_string

lds dx,point_fname ;формируем указатель на строку string

mov ah,40h ;.номер функции DOS

int 21h ;выводим

jc exit ;переход в случае ошибки

nop ;для тестирования

Чтение из файла или устройства

Чтение из файла в область памяти осуществляется функцией 3Fh. Вход: АН = 3Fh; BX = дескриптор файла; СХ = количество байтов для чтения; DS-.DX — указатель на область памяти, в которую помещаются прочитанные байты. Выход: CF = 0 — АХ = число действительно прочитанных байтов из файла; CF = 1 — АХ = код ошибки: 5 — в доступе отказано; 6 — недопустимый дескриптор.

Чтение данных производится начиная с текущей позиции в файле, которая после успешного чтения смещается на значение, равное количеству прочитанных байтов. Если в качестве файла используется стандартная консоль (клавиатура), то чтение производится до первого символа CR (carriage return) с кодом 0dh, соответствующего нажатию клавиши Enter. Это, кстати, еще один способ ввода данных с клавиатуры в программу. Кроме символов введенной строки в ее конец помещаются символы 0dh и 0ah. Это необходимо учитывать при задании размера буфера для ввода. Способ ввода данных с экрана с помощью функции 3Fh иллюстрирует приведенный ниже пример программы.

:prg07_10.asm - программа демонстрации ввода данных с экрана с помощью функции 3Fh.

.data

string db 80 dup (" ")

1en_string=$-string

point_fname dd string

.code

;.........вводим с экрана......-----.....----------------

mov bx,0 ;стандартный дескриптор – клавиатура

mov cx,len_string

lds dx,point_fname ;формируем указатель на строку string

mov ah,3fh ;номер функции DOS

int 21h

jc exit ;переход в случае ошибки

;---------выводим на экран---------------------...........

;две строки ниже в данном случае можно опустить

mov bx,1 ;стандартный дескриптор – экран

mov cx, len_string

lds dx,point_fname ;формируем указатель на строку string

mov ah,40h ;номер функции DOS

int 21h ;открываем файл

jc exit ;переход в случае ошибки

Создание каталога

Вход: АН = 39h; DS:DX — ASCIZ-строка пути к создаваемому каталогу. Выход: АХ = не определен (CF = 0); АХ - код ошибки (CF = 1): 3 — несуществующий путь; 5 — доступ запрещен. Путь к каталогу должен содержать перечисление всех каталогов начиная от корневого на пути к создаваемому каталогу, при этом они, естественно, должны существовать. Последнее имя каталога — имя создаваемого каталога.

;prg07_15.asm - программа демонстрации создания каталога функцией 39h.

.data

dname db "c:\windows\my_dir",0

point_dname dd dname

.code

;.....создадим каталог в каталоге c:\windows.......-.......

lds dx,point_dname ;формируем указатель на строку с именем нового каталога

mov ah,39h ;номер функции DOS

int 21h

jc exit ;переход в случае ошибки

Удаление каталога

Вход: АН = 3Ah; DS:DX — ASCIZ-строка пути к удаляемому каталогу. Выход: CF = 0 — АХ = не определен; АХ = код ошибки (CF = 1): 3 — несуществующий путь; 5 — доступ запрещен; 10h — попытка удаления текущего каталога. Удаляемый каталог должен быть пустым.

:prg07_16.asm - программа демонстрации удаления каталога функцией 3Аh.

.data

dname db "c:\windows\my_dir",0

point_dname dd dname .code

:----удалим каталог my_dir в каталоге c:\windows---------

lds dx, point_dname ;формируем указатель на строку с именем нового каталога

mov ah,3ah ;номер функции DOS

int 21h

jc exit ;переход в случае ошибки

Изменить текущий каталог

MS DOS позволяет установить текущий каталог для того, чтобы не указывать полный путь для последующих операций с файлами. При необходимости можно получить полный путь к текущему каталогу в виде ASCIZ-строки. Вход: АН = 3Bh; DS:DX — указатель на буфер, содержащий полный путь от корневого каталога в виде ASCIZ-строки (до 64 байт). Выход: CF = 0 — АХ = не определен; CF = 1 — АХ = код ошибки: 03h — путь не найден.