переменная Z служит указателем на первый байт процедуры. В прило-
жении Г объясняется как вставлять ассемблерные процедуры в прог-
раммы на Бейсике. Hомер накопителя устанавливается в строке 110,
причем 0 = A, 1 = B и т.д. Если назначить накопителем по умолча-
нию несуществующий накопитель, то ошибки не будет, поэтому будьте
внимательны. Hе пытайтесь объединить строки 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 устанавливает накопитель по умолча-
нию. Hадо просто поместить номер накопителя (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].
Hаоборот, оператор CLOSE не уничтожает файл. Вместо этого для
уничтожения файла используется оператор KILL. Для того чтобы
уничтожить файл его не надо открывать. Просто поместите имя файла
в кавычках, например KILL "A:ACCOUNT.DAT". Или, если файл нахо-
дится в другом подкаталоге, то надо использовать стандартный путь
к файлу, например KILL "A:\FINANCES\ACCOUNT.DAT". В обоих случаях
имя накопителя необходимо указывать только если файл находится не
на накопителе по умолчанию. Отметим, что Вы не можете воспользо-
ваться этим методом, чтобы удалить подкаталог (который является
одним из видов файла) - вместо этого используйте RMDIR.
Средний уровень.
Файл может быть создан или уничтожен с помощью либо метода
управляющего блока файла, либо метода дескриптора файла. Создание
файла одним из методов ни в коей мере не ограничивает будущий
доступ к нему только этим методом. Hо, поскольку одновременно с
созданием он открывается, то при создании необходимо использовать
тот метод, с помощью которого Вы будете работать с этим файлом на
этот раз. Kогда файл создается, а затем закрывается и при этом в
него ничего не записывается, то ему соответствует элемент катало-
га с нулем в поле длины файла, однако дисковое пространство этому
файлу не отводится. Важно понимать, что когда последовательный
файл открывается для записи (а не для добавления) данных, то
используется именно эта функция создания файла, поэтому файл
обрезается до нулевой длины и затем полностью перезаписывается.
Метод 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]. K обычно-
му FCB надо добавить 7-байтный заголовок, начиная с байта FFH,
затем должны следовать 5 байтов ASCII 0, а затем нужный байт
атрибутов. Для создания спрятанного файла необходимо, чтобы был
установлен бит 1 байта атрибутов. Чтобы спрятать файл, открытый в
приведенном примере, напишите:
FCB DB 0FFH,5 DUP(0),2,1,'MYFILE DAT',25 DUP(0)
Функция 13H прерывания 21H уничтожает файл. Hадо чтобы 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,
включая имя накопителя, если файл находится не на накопителе по
умолчанию. Строка должна завершаться байтом ASCII 0. Байт атрибу-
тов файла [5.2.6] поместите в CX (0 - для нормального файла).
Затем выполните функцию. При успешном выполнении флаг переноса
будет равен нулю, а в AX будет возвращен номер нового файла. При
возникновении ошибки флаг переноса устанавливается в 1, а в AX
содержится код ошибки, который может быть равен 3, если не найден
путь, 4 - если уже открыты все буфера для файлов и 5 - если ката-
лог полон или файл уже существует со статусом только для чтения.
Отметим, что если в каталоге уже существует файл с таким именем,
то существующий файл обрезается до нулевой длины, и тем самым
разрушается. Для избежания ошибок надо предварительно использо-
вать функцию 4EH прерывания 21H для проверки.
;---в сегменте данных
PATH DB 'B:LEVEL1\LEVEL2\FILENAME.EXT',0
;---проверка наличия файла в каталоге
MOV AH,4EH ;функция поиска в каталоге
LEA DX,PATH ;DS:DX указывают на путь
INT 21H ;проверка наличия файла
JNC WARN_USER ;если есть, то сообщаем
;---создание файла
MOV AH,3CH ;функция создания файла
MOV CX,0 ;нормальные атрибуты
INT 21H ;создаем файл
JC OPEN_ERROR ;уход на обработку ошибки
MOV HANDLE,AX ;запоминаем номер файла
В MS DOS 3.0 добавлена новая функция для создания файла мето-
дом дескриптора файла. Это функция номер 5BH прерывания 21H. Она
работает в точности так же, как и описанная функция 3CH, за иск-
лючением того, что она возвращает расширенные коды ошибок, что
позволяет лучше обрабатывать ошибочные ситуации. Они объяснены в
[7.2.5].
Для уничтожения файла методом дескриптора файла используйте
функцию 41H прерывания 21H. И опять DS:DX должны указывать на
строку, дающую путь и имя файла. Джокеры в имени файла не допус-
каются. Затем вызовите функцию. Если при возврате флаг переноса
установлен, то функция не выполнена; в этом случае AL будет со-
держать 2, если файл не найден и 5 - если произошла ошиька на
диске. Отметим, что с помощью этой функции Вы не можете удалить
файл со статусом только для чтения; измените атрибуты файла
[5.2.6] перед его удалением. Вот пример:
;---в сегменте данных
PATH DB 'B:LEVEL1\LEVEL2\FILENAME.EXT',0
;---уничтожаем файл
MOV AH,41H ;номер функции уничтожения
LEA DX,PATH ;DS:DX указывают на путь
INT 21H ;уничтожаем файл
JC DELETE_ERROR ;на обработку ошибки
MS DOS версии 3.0 имеет специальную функцию (5AH прерывания
21H) для создания временного "безымянного" файла. Операционная
система сама генерирует имя для файла и проверяет, что такого
файла еще нет в каталоге. При этом исключается всякая возможность
что при создании временного файла будет разрушен существующий
файл с совпадающим именем. При входе DS:DX должны указывать на
строку пути к каталогу, в котором должен быть создан временный
файл. Строка должна завершаться обратной косой чертой. Поместите
атрибуты файла в CX (обычно 0). При возврате AX будет содержать
номер файла, если только флаг переноса не установлен, в этом
случае AX содержит информацию об ошибке. Произвольное имя файла
добавляется к концу строки пути. Эта функция может возвращать
расширенные коды ошибок, которые существуют только в MS DOS 3.0;
они объясняются в [7.2.5]. Файл, созданный этой функцией не унич-
тожается автоматически - программа должна использовать функцию
41H (см. выше). В данном примере программа создает временный
файл, а затем уничтожает его:
;---в сегменте данных
PATH DB 'B:LEVEL1\LEVEL2\',12 DUP(0)
;---создаем временный файл
MOV AH,5AH ;номер функции
LEA DX,PATH ;DS:DX указывают на путь
INT 21H ;создаем временный файл
JC CREATION_ERROR ;уход на обработку ошибки
.
.
MOV AH,41H ;номер функции
LEA DX,PATH ;DS:DX указывают на путь
INT 21H ;уничтожаем временный файл
JC DELETION_ERROR ;уход на обработку ошибки
5.3.3 Открытие/закрытие файла.
"Открыть" файл - это значит создать небольшие блоки памяти,
которые будут содержать информацию о файле и служить промежуточ-
ной станцией (буфером), через которую данные будут передаваться
между файлом и памятью. Языки высокого уровня автоматически соз-
дают для Вас эти блоки, а язык ассемблера - нет. При открытии