ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.07.2020
Просмотров: 3150
Скачиваний: 1
MOV AL,7 ;число секторов каталога
MOV AH,2 ;номер функции чтения
INT 13H ;читаем каталог в память
;---ищем метку тома, сравнивая байт атрибутов с 8
MOV CX,112 ;число элементов
ADD BX,11 ;смещение для атрибутов
TRY_AGAIN: MOV AL,[BX] ;берем 1-й элемент
CMP AL,8 ;это метка тома?
JE GOT_IT ;если да, то уход
ADD BX,32 ;иначе на след. элемент
LOOP TRY_AGAIN ;
;---выводим сообщение об отсутствии метки тома
MOV AH,9 ;функция вывода строки
LEA DX,NO_LABEL ;указываем на строку
INT 21H ;выводим ее
JMP SHORT CONTINUE ;на конец
;---выводим строку, дающую метку тома
GOT_IT: MOV AH,9 ;функция вывода строки
LEA DX,VOL_STRING ;указываем на строку
INT 21H ;выводим ее
SUB BX,11 ;указатель на метку
MOV CX,11 ;пишем 11 символов
MOV AH,2 ;функция вывода символов
NEXT_CHAR: MOV DL,[BX] ;символ в DL
INT 21H ;выводим символ
INC BX ;переходим к следующему
LOOP NEXT_CHAR ;
CONTINUE:
Чтобы стереть метку поместите следующий код в GOT_IT:
GOT_IT: MOV AL,0E5H ;код отметки пустого элемента
SUB BX,11 ;указатель на начало элемента
MOV [BX],AL ;меняем первый байт
Чтобы изменить метку тома, надо вместо этого использовать в
GOT_IT следующий код. Предполагается, что Вы подготовили где-то
11-байтную строку NEW_LABEL.
GOT_IT: LEA SI,NEW_LABEL ;SI должен указывать на строку
SUB BX,11 ;BX указывает на начало метки
MOV DI,BX ;помещаем указатель в DI
MOV CX,11 ;пересылка 11 символов
REP MOVSB ;пересылаем строку
Чтобы создать метку можно использовать тот же самый код, но
надо также установить байт атрибутов равный 8 (Вы можете просто
добавить ASCII 8 к строке, содержащей новую метку, так как байт
атрибутов непосредственно следует за самой меткой).
И, наконец, во всех случаях изменения каталога, необходимо
записать каталог обратно на диск. Ошибки при этом непростительны.
;---запись измененных секторов назад на диск
MOV AX,SEG DIR_AREA ;регистры как и при чтении
MOV ES,AX ;
MOV BX,OFFSET DIR_AREA ;
MOV DL,0 ;
MOV DH,0 ;
MOV CH,0 ;
MOV CL,6 ;
MOV AL,7 ;
MOV AH,3 ;номер функции записи секторов
INT 13H ;
Раздел 3. Подготовка к работе с файлами.
Программы, написанные на языках высокого уровня могут просто
открыть файл и вся подготовительная работа для операций с файлами
будет выполнена автоматически. Однако программисты на языке ас-
семблера должны создать специальные области данных, которые ис-
пользуются при операциях ввода/вывода. MS DOS использует два
метода доступа к файлам, метод управляющего блока файла (FCB) и
метод дескриптора файла. Метод FCB сохранился с тех пор, когда MS
DOS не работала с древовидной структурой каталогов, поэтому с его
помощью можно получить доступ только к файлам, находящимся в
текущем каталоге. Метод дескриптора файла позволяет получить
доступ к любому файлу, независимо от того, какой каталог является
текущим.
Поскольку теперь древовидная структура каталогов широко ис-
пользуется, то метод FCB становится анахронизмом, однако MS DOS
продолжает поддерживать этот метод, чтобы сохранить совместимость
со старым программным обеспечением и по этой причине мы рассмот-
рим и его. Однако в своих программах всегда используйте метод
дескриптора файла. Метод дескриптора файла имеет дополнительное
преимущество в том, что он требует меньше подготовительной рабо-
ты. Однако в некоторых приложениях сами операции ввода/вывода при
его использовании могут оказаться более сложными, чем в методе
FCB. Например, операции чтения файла с прямым доступом с исполь-
зованием метода дескриптора файла требуют чтобы программа вычис-
ляла смещение каждой записи в файле, в то время как соответствую-
щая функция FCB получает номер записи и делает необходимые вычис-
ления сама.
Прежде чем читать или писать данные файл должен быть открыт.
Открыть файл это значит создать и инициализировать специальную
область данных, используемую MS DOS, которая содержит важную
информацию о файле, такую как имя файла, имя накопителя, размер
записи файла и т.д. Языки высокого уровня, такие капк Бейсик,
создают эти области автоматически. Одной из таких областей яв-
ляется управляющий блок файла и когда используется метод FCB, то
программа создает этот блок, а MS DOS читает и манипулирует его
содержимым. Первоначально FCB содержит только имя файла и имя
накопителя; после того как файл открывается в него добавляется
информация о размере записи файла и о текущей позиции, с которой
к нему будет осуществляться доступ.
С другой стороны, при доступе с помощью дескриптора файла MS
DOS автоматически создает область данных для файла в произвольном
месте. Затем MS DOS создает уникальный 16-битный код номера файла
и впоследствии этот "номер" используется функциями DOS для иден-
тификации того, с каким из открытых файлов производится операция.
Все что нужно для нахождения файла - это стандартная строка пути,
в которой может быть необязательное имя накопителя и имена подка-
талогов должны быть разделены обратной косой чертой. Эти строки
отличаются от стандартного запроса MS DOS только тем, что они
должны завершаться байтом ASCII 0, с тем чтобы программа могла
найти конец строки (такие строки называются строками ASCIIZ).
Операции по пересылке данных из или в файл требуют, чтобы была
указана область памяти в которую или из которой будут направлять-
ся данные. Такой буфер определяется отведением ему места в памяти
и установкой указателя на его первый байт (т.е. на младший адрес
буфера в памяти). Если передано слишком много данных, то буфер
переполняется и может разрушить данные, расположенные в следующих
адресах памяти. Буфер может использоваться как промежуточный
буфер, работающий только с небольшой порцией данных для операций
чтения или записи. Или буфер может помещаться в область памяти, в
которой программа действительно хранит и обрабатывает данные.
Функции доступа через управляющий блок файла определяют проме-
жуточный буфер с помощью указателя, которой все время хранится
операционной системой. Этот буфер называется область обмена с
диском (disk transfer area) или DTA. К сожалению, техническая
документация по IBM PC часто называет термином DTA указатель на
буфер, хотя на самом деле правильно называть его указателем на
DTA. После того как указатель на DTA установлен с помощью спе-
циальной функции, все файловые операции используют его до тех пор
пока он не будет изменен. С другой стороны, функции, использующие
дескриптор файла, должны указывать стартовый адрес буфера обмена
каждый раз при вызове функции и они игнорируют указатель на DTA,
используемый функциями управляющего блока файла. Рисунок 5-2
показывает два метода доступа к файлам.
5.3.1 Установка/проверка накопителя по умолчанию.
Программы могут экономить часть работы, назначая накопитель по
умолчанию, на котором содержатся файлы данных. Если в начале
программы запросить у пользователя какой накопитель он будет
использовать, то впоследствии не будет сомнений к какому накопи-
телю следует обращаться.
Высокий уровень.
В приведенной программе на Бейсике текущий накопитель по умол-
чанию переключается с помощью процедуры на машинном языке. Проце-
дура имеет длину всего 7 байтов. Она помещается в строку X$, а
переменная Z служит указателем на первый байт процедуры. В прило-
жении Г объясняется как вставлять ассемблерные процедуры в прог-
раммы на Бейсике. Номер накопителя устанавливается в строке 110,
причем 0 = A, 1 = B и т.д. Если назначить накопителем по умолча-
нию несуществующий накопитель, то ошибки не будет, поэтому будьте
внимательны. Не пытайтесь объединить строки 120 и 130 этой проце-
дуры, поскольку в этом случае интерпретатор Бейсика будет обраба-
тывать их неправильно.
100 DEF SEG 'сегмент на начало области Бейсика
110 NUM = 0 'выбираем накопитель A
120 X$ = CHR$(180)+CHR$(14)+CHR$(178)+CHR$(NUM)+CHR$(205)+
CHR(33)+CHR$(223)
130 Y = VARPTR(X$) 'получаем дескриптор строки (адрес в Y+1)
140 Z = PEEK(Y+1)+PEEK(Y+2)*256 'вычисляем адрес строки
150 CALL Z 'выполняем машинную процедуру
Средний уровень.
Функция EH прерывания 21H устанавливает накопитель по умолча-
нию. Надо просто поместить номер накопителя (0 = A, 1 = B и т.д.)
в DL и выполнить прерывание. Эта функция возвращает в AL число
накопителей на машине. Отметим, что когда у машины имеется только
один накопитель, то возвращается число 2. Лучший способ определе-
ния числа накопителей у машины описан в [1.1.5].
MOV AH,0EH ;номер функции
MOV DL,1 ;код для накопителя B
INT 21H ;устанавливаем накопитель по умолчанию
Функция 19H прерывания 21H сообщает какой из накопителей яв-
ляется накопителем по умолчанию. Для этой функции нет входных
регистров. При возврате в AL содержится кодовый номер, где 0 = A,
1 = B и т.д.
5.3.2 Создание/удаление файла.
Можно создать файл, не помещая в него никакой информации.
Создается элемент каталога, а длина файла устанавливается равной
0. При удалении файла соответствующий элемент каталога на самом
деле не удаляется, он просто становится недействующим за счет
изменения первого байта элемента (первого символа имени файла) на
E5H. Впоследствии этот элемент может быть перезаписан при созда-
нии нового файла. Во время удаления файла вносятся также измене-
ния в таблицу размещения файлов, с тем чтобы сектора используемые
этим файлом были доступны для других файлов. Само содержимое этих
секторов при этом не стирается. Поэтому можно восстановить уда-
ленный файл - однако предупреждаем, что операции с таблицей раз-
мещения файлов надо производить очень осторожно.
Высокий уровень.
Бейсик не имеет специальной команды для создания файла. Вместо
этого при открытии файла указанное имя ищется в каталоге и, если
оно не найдено, то создается новый файл. Если открыть новый файл,
а затем закрыть его не производя в него записи, то он останется
в каталоге с длиной 1 байт и ему будет отведен кластер дискового
пространства (единственный байт - это символ Ctrl-Z - ASCII 26 -
который используется в качестве признака конца стандартного текс-
тового файла). Детали оператора OPEN см. в [5.3.3].
Наоборот, оператор CLOSE не уничтожает файл. Вместо этого для
уничтожения файла используется оператор KILL. Для того чтобы
уничтожить файл его не надо открывать. Просто поместите имя файла
в кавычках, например KILL "A:ACCOUNT.DAT". Или, если файл нахо-
дится в другом подкаталоге, то надо использовать стандартный путь
к файлу, например KILL "A:\FINANCES\ACCOUNT.DAT". В обоих случаях
имя накопителя необходимо указывать только если файл находится не
на накопителе по умолчанию. Отметим, что Вы не можете воспользо-
ваться этим методом, чтобы удалить подкаталог (который является
одним из видов файла) - вместо этого используйте RMDIR.
Средний уровень.
Файл может быть создан или уничтожен с помощью либо метода
управляющего блока файла, либо метода дескриптора файла. Создание
файла одним из методов ни в коей мере не ограничивает будущий
доступ к нему только этим методом. Но, поскольку одновременно с
созданием он открывается, то при создании необходимо использовать
тот метод, с помощью которого Вы будете работать с этим файлом на
этот раз. Когда файл создается, а затем закрывается и при этом в
него ничего не записывается, то ему соответствует элемент катало-
га с нулем в поле длины файла, однако дисковое пространство этому
файлу не отводится. Важно понимать, что когда последовательный
файл открывается для записи (а не для добавления) данных, то
используется именно эта функция создания файла, поэтому файл
обрезается до нулевой длины и затем полностью перезаписывается.
Метод FCB:
Функция 16H прерывания 21H создает и открывает файл. Создайте
FCB с именем файла и накопителя и пусть DS:DX указывает на него.
Затем вызовите функцию. Просматривается каталог и если найден
совпадающий элемент, то снова используется именно этот элемент
каталога, при этом новый файл перекрывает старый с тем же именем.
Чтобы избежать непреднамеренного разрушения файлов, сначала про-
верьте на наличие файла с таким именем, используя функцию 11H
прерывания 21H [5.2.1]. Если нет файла с таким именем, то соз-
дается новый элемент каталога и в AL возвращается 0; если каталог
полон, то в AL возвращается FF. Чтобы присвоить файлу специальные
атрибуты (например, статус только для чтения) [5.2.6] используйте
расширенный управляющий блок файла [5.3.5]. При открытии новый
файл инициализируется с нулевой длиной и ему отводится кластер
дискового пространства. Вот пример:
;---в сегменте данных
FCB DB 1,'MYFILE DAT',25 DUP(0)
;---проверка наличия такого файла
MOV AH,11H ;функция поиска файла
LEA DX,FCB ;DS:DX указывают на FCB
INT 21H ;ищем файл
CMP AL,0 ;AL = 0 если файл существует
JE WARN_USER ;если да, то сообщаем об этом
;---создание файла
MOV AH,16H ;номер функции создания файла
INT 21H ;создаем файл
Для создания файла со специальными атрибутами, например стату-
сом только для чтения, надо использовать расширенный управляющий
блок файла. Байт атрибутов файла обсуждается в [5.2.6]. К обычно-
му FCB надо добавить 7-байтный заголовок, начиная с байта FFH,
затем должны следовать 5 байтов ASCII 0, а затем нужный байт
атрибутов. Для создания спрятанного файла необходимо, чтобы был
установлен бит 1 байта атрибутов. Чтобы спрятать файл, открытый в
приведенном примере, напишите:
FCB DB 0FFH,5 DUP(0),2,1,'MYFILE DAT',25 DUP(0)
Функция 13H прерывания 21H уничтожает файл. Надо чтобы DS:DX
указывали на неоткрытый FCB и выполнить функцию. Если не найдено
файла с указанным именем, то в AL возвращается FF, иначе 0. В
имени файла могут использоваться джокеры (знаки вопроса, но не
звездочки) и в этом случае за одно обращение к функции может быть
удалено несколько файлов. Вот пример:
;---в сегменте данных
FCB DB 1,'MYFILE DAT',25 DUP(0)
;---удаляем файл
MOV AH,13H ;номер функции удаления файла
LEA DX,FCB ;DS:DX указывают на FCB
INT 21H ;удаляем файл
CMP AL,0FFH ;проверка на ошибку
JE DELETE_ERROR ;уход на обработку ошибки
Метод дескриптора файла:
Функция 3CH прерывания 21H создает и открывает новый файл
методом дескриптора файла. DS:DX должны указывать на строку,
дающую путь к файлу и имя файла в стандартном формате MS DOS,