Дисковая память II: Функции базовой версиии DOS
------------------------------------------------------------ Дисковая память II: Функции базовой версиии DOS
Цель: Раскрыть основные требования к программированию функций базовой версии DOS для обработки дисковых файлов.
ВВЕДЕНИЕ ------------------------------------------------------------
В начале данной главы рассматриваются функции базовой версии DOS, определяющие блок управления файлом (FCB), а затем будут показаны возможности создания и обработки дис ковых файлов последовательным и прямым доступом. Все рассмат риваемые операции были введены в первых версиях DOS и возмож ны во всех последующих версиях. Обработка дисковых файлов в базовой DOS включает определе ние блока управления файлом (FCB - file control block), кото рый описывает файл и его записи. Передача адреса блока FCB в DOS обязательна для всех дисковых операций ввода-вывода. Новых команд ассемблера в данной главе не потребуется. Управление вводом и выводом осуществляется специальными прерываниями. Запись файла на диск требует, чтобы прежде он был "создан" и DOS смогла сгенерировать соответствующий эле мент в оглавлении. Когда все записи файла будут записаны, программа должна "закрыть" файл, так, чтобы DOS завершила обработку оглавления. Чтение файла требует, чтобы он был сначала "открыт" для того, чтобы убедиться в его существо вании. Так как записи имеют фиксированную длину и в силу соответствующей организации оглавления, обработка записей дискового файла может осуществляться как последовательно, так и произвольно. Метод доступа к дисковой памяти, поддерживающий использо вание оглавления, "блокирование" и "разблокирование" запи сей, обеспечивается прерыванием DOS 21H. Более низкий уро вень, обеспечивающий абсолютную адресацию дисковых секторов, также через DOS, выполняется посредством прерываний 25H и 26H. Самый низкий уровень обеспечивается прерыванием BIOS 13H, которое позволяет выполнить произвольную адресацию в дисковой памяти по номеру дорожки и сектора. Методы DOS осу ществляют некоторую предварительную обработку до передачи управления в BIOS. В главе 17 объясняется применение пред почтительных функций расширенного DOS 2, а глава 18 пред ставляет основные дисковые операции в BIOS. Напоминание: Термин кластер определяет один или более секторов с данными в зависимости от дискового устройства.
БЛОК УПРАВЛЕНИЯ ФАЙЛОМ (FCB) ------------------------------------------------------------ Для выполнения операций ввода-вывода на диске в базовой DOS необходимо в области данных определить блок FCB. Блок FCB не поддерживает путь доступа к файлу, поэтому он исполь зуется главным образом для обработки файлов в текущей дирек
Ассемблер для IBM PC. Глава 16. 2
тории. Блок FCB содержит описание файла и его записей в приведенном ниже формате. Пользователь должен инициализи ровать байты 0-15 и 32-36, байты 16-31 устанавливается DOS.
Байты Назначение 0 Указывает дисковод: 01 для дисковода A, 02 для B и т.д. 1-8 Имя файла, выравненное по левой границе с конечными пробелами, если имя меньше 8 байт. Поле может содержать зарезервированные имена, например, LPT1 для принтера. 9-11 Тип файла для дополнительной идентификации, например, DTA или ASM. Если тип файла меньше трех байт, то он должен быть выравнен по левой границе и дополнен конечными пробелами. DOS хранит имя и тип файла в оглавлении. 12-13 Номер текущего блока. Блок содержит 128 записей. Для локализации конкретной записи используется номер текущего блока и номер текущей записи (байт 32). Первый блок файла имеет номер 0, второй - 1 и т.д. Операция открытия файла устанавливает в данном поле 0. 14-15 Логический размер записи. Операция открытия инициа лизирует размер записи значением 128 (шест.80). После открытия и перед любой операцией чтения или записи можно устанавливать в данном поле любое тре буемое значение длины записи. 16-19 Размер файла. При создании файла DOS вычисляет и записывает это значение (произведение числа запи сей на размер записей) в оглавление. Операция открытия выбирает размер файла из оглавления и заносит его в данное поле. Программа может читать это поле, но не может менять его. 20-21 Дата. При создании или последней модификации файла DOS записывает дату в оглавление. Операция открытия выбирает дату из оглавления и заносит в данное поле. 22-31 Зарезервировано для DOS. 32 Текущий номер записи. Данное поле содержит текущий номер записи (О-127) в текущем блоке (см.байты 12-13). Система использует текущие значения блока и записи для локализации записи в дисковом файле. Обычно номер начальной записи в данном поле - 0, но его можно заменить для начала последовательной обработки на любое значение от 0 до 127. 33-36 Относительный номер записи. Для произвольного дос тупа при операциях чтения или записи данное поле должно содержать относительный номер записи. Напри мер, для произвольного чтения записи номер 25 (шест.19), необходимо установить в данном поле шест 19000000. Произвольный доступ характеризует ся тем, что система автоматически преобразует относительный номер записи в текущие значения
Ассемблер для IBM PC. Глава 16. 3
блока и записи. Ввиду ограничения на максимальный размер файла (1.073.741.824 байтов), файл с короткими записями может содержать больше записей и иметь больший относительный номер записи. Если размер записи больше 64, то байт 36 всегда содер жит 00.
Помните, что числовые значения в словах и двойных словах записываются в обратной последовательности байтов. Блоку FCB предшествует необязательное семибайтовое расши рение, которое можно использовать для обработки файлов со специальными атрибутами. Для использования расширения необхо димо закодировать в первом байте шест.FF, во втором - атри бут файла, а в остальных пяти байтах шесь.нули.
ИСПОЛЬЗОВАНИЕ БЛОКА FCB ДЛЯ СОЗДАНИЯ ФАЙЛА НА ДИСКЕ ------------------------------------------------------------ Для ссылки на каждый дисковый файл программа должна содер жать правильно составленный блок управления файлом. Операции ввода-вывода на диск требуют установки адреса блока FCB в регистре DX. Доступ к полям блока FCB осуществляются по этому адресу с помощью регистровой пары DS:DX. Для создания нового файла программа использует функцию шест.16 в прерыва нии DOS INT 21H следующим образом:
MOV AH,16H ; Создание LEA DX,FCBname ; дискового файла INT 21H ; Вызов DOS
DOS осуществляет поиск имени файла и тип файла, взятого из соответствующих полей FCB, в оглавлении. Если элемент оглавления, содержащий необходимое имя (и тип), будет найдено, то DOS очищает найденный элемент для нового исполь зования, если такой элемент не будет найден, то DOS ищет свободный элемент. Затем операция устанавливает размер файла в 0 и "открывает" файл. На этапе открытия происходит проверка доступного дискового пространства, результат такой проверки устанавливается в регистре AL:
00 На диске есть свободное пространство FF На диске нет свободного пространства.
При открытии также устанавливается в блок FCB номер текущего блока - 0 и размер записей (по умолчанию) - 128 (шест.80) байтов. Прежде, чем начать запись файла, можно заменить это значение по умолчанию на требуемый размер записей. Для определения выводной записи необходимо прежде обеспе чить начальный адрес этой записи в область передачи данных (DTA - disk trausfer area). Так как блок FCB содержит размер записей, то в DTA не требуется устанавливать ограничитель конца записи. Затем с помощью функции шест.1A необходимо
Ассемблер для IBM PC. Глава 16. 4
сообщить DOS адрес DTA. В любой момент времени может быть активен только один DTA. В следующем примере инициализи руется адрес DTA:
MOV AH,1AH ; Установка адреса LEA DX,DTAname ; DTA INT 21H ; Вызов DOS
Если программа обрабатывает только один дисковой файл, то должна быть только одна установка адреса DTA для всего выполнения. При обработке нескольких файлов программа должна устанавливать соответствующий адрес DTA непосредственно перед каждой операцией чтения или записи. Для последовательной записи на диск существует функция шест. 15:
MOV AH,15 ; Последовательная LEA DX,FCBname ; запись INT 21H ; Вызов DOS
Операция записи использует информацию из блока FCB и адрес текущего буфера DTA. Если длина записи равна размеру сектора, то запись заносится на диск. В противном случае записи заполняют буфер по длине сектора и затем буфер записы вается на диск. Например, если длина каждой записи состав ляет 128 байтов, то буфер заполняется четырьмя записями (4*128=512) и затем буфер записывается в дисковой сектор. После успешного занесения записи на диск DOS увеличивает в блоке FCB размер файла на размер записи и текущий номер записи на 1. Когда номер текущей записи достигает 128, про исходит сброс этого значения в 0 и в FCB увеличивается номер текущего блока на 1. Операция возвращает в регистре AL сле дующие коды:
00 Успешная запись. 01 Диск полный. 02 В области DTA нет места для одной записи.
Когда запись файла завершена, можно, хотя и не всегда обязательно, записать маркер конца файла (шест.1A). Для за крытия файла используется функция шест.10:
MOV AH,10H ; Закрыть LEA DX,FCBname ; файл INT 21H ; Вызов DOS
Эта операция записывает на диск данные, которые еще остались в дисковом буфере DOS и изменяет в соответствующем элементе оглавления, дату и размер файла. В регистре AL возвращаются следующие значения:
00 Успешная запись. FF Описание файла оказалось в неправильном
Ассемблер для IBM PC. Глава 16. 5
элементе оглавления (возможно в результате смены дискеты).
ПРОГРАММА: ИСПОЛЬЗОВАНИЕ FCB ДЛЯ СОЗДАНИЯ ФАЙЛА НА ДИСКЕ ------------------------------------------------------------ Программа, приведенная на рис.16.1, создает дисковый файл по имени, которое вводится пользователем с клавиатуры. Блок FCB (FCBREC) в данной программе содержит следующие поля:
FCBDRIV Программа должна создать файл на диске в дисководе 4 (или D). FCBNAME Имя файла - NAMEFILE. FCBEXT Тип файла - DAT. FCBBLK Начальное значение номера текущего блока - 0. FCBRCSZ Размер записей неопределен, так как операция откры тия устанавливает в данном поле значение 128. FCBSQRC Начальное значение номера текущей записи - 0.
В программе организованы следующие процедуры:
BEGIN Инициализирует сегментные регистры, вызывает C10OPEN для создания файла и установки адреса DTA для DOS, вызывает D10PROC для ввода имени файла. Если ввод пустой, то происходит вызов 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
Ассемблер для IBM PC. Глава 16. 6
------------------------------------------------------------ ------------------------------------------------------------ Рис. 16.1. Создание дискового файла.
Операция закрытия заносит во второй сектор оставшиеся в буфере девять записей и изменяет в оглавлении дату и рвзмер файла. Размер записывается байтами в переставленном порядке: 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
Ассемблер для IBM PC. Глава 16. 7
Для последовательного чтения записей с диска используется функция шест.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 ДЛЯ ЧТЕНИЯ ДИСКОВОГО ФАЙЛА ------------------------------------------------------------ На рис.16.2 приведена программа, которая выполняет чтение файла, созданного предыдущей программой, и вывод на экран имен из записей файла. Обе программы содержат идентичные блоки FCB, хотя, имена полей FCB могут быть различны. Содержимое полей имени и типа файла должны быть одинаковы. Программа содержит следующие процедуры:
BEGIN Инициализирует сегментны регистра, вызывает про цедуру E10OPEN для открытия файла и установки DTA и вызывает F10READ для чтения записей. Если считан маркер конца файла, то программа завершается, если нет, то вызывается процедура G10DISP. E10OPEN Открывает файл, устанавливает значение размера и записей, равное 32 (шест.20), и инициализирует адрес DTA.
Ассемблер для IBM PC. Глава 16. 8
F10READ Выполняет последовательное чтение записей. Опера ция чтения автоматически увеличивает номер текущей запи си в блоке FCB. G10DISP Выводит на экран содержимое прочитанной записи. X10ERR Выводит на экран сообщение об ошибке в случае некорректной операции открытия или чтения.
------------------------------------------------------------ ------------------------------------------------------------ Рис. 16.2. Чтение дискового файла
Операция открытия выполняет поиск имени и типа файла в оглавлении. Если необходимый элемент оглавления найден, то автоматически в блок FCB заносятся размер файла, дата и длина записей. Первая операция чтения записи с номером 00 получает доступ к диску и считывает весь сектор (16 записей) в буфер. После этого первая запись заносится в DTA, а номер текущей записи в FCB увеличивается с 00 до 01:
Буфер: |запись 00|запись 01|запись 02|... |запись 15| DTA : |запись 00| Второй операции чтения нет необходимого обращаться к дис ку. Так как требуемая запись уже находится в буфере, то опе рация просто пересылает запись 01 из буфера в DTA и увели чивает номер текущей записи на единицу. Таким же образом вы полняются следующие операции чтения пока все 16 записей из буфера не будут обработаны. Операции чтения 16-ой записи приводит к физическому чтению следующего сектора в буфер и пересылка первой записи сектора в DTA. Последующие операции чтения переносят осталь ные записи из буфера в DTA. Попытка прочитать после последней записи вызовет состояние конца файла и в регистр AL будет записан код возврата шест. 01.
ПРЯМОЙ ДОСТУП ------------------------------------------------------------ До сих пор в этой главе рассматривалась последовательная обработка дисковых файлов, которая адекватна как для созда ния файла, так и для печати его содержимого или внесения из менений в небольшие файлы. Если программа ограничена только возможностью последовательной обработки, то для изменения файла она должна считывать каждую запись, вносить изменения в определенные из них и заносить записи в другой файл (программа может использовать один DTA, но потребуются различные блоки FCB). Обычной практикой является чтение входного файла с диска A и запись обновленного файла на диск B. Преимущество этого способа состоит в том, что он автома тически оставляет резервную копию. В некоторых случаях применяется доступ к конкретным записям файла для получения информации, например, нескольких служащих или о части ассортимента товаров. Для доступа, скажем, к 300-ой записи файла, последовательная обработка
Ассемблер для IBM PC. Глава 16. 9
должна включать чтение всех 299 предшествующих записей, пока не будет получена 300-я запись. Примечание: система может начать обработку с конкретного номера блока и записи). Несмотря на то, что файл создается последовательно, доступ к записям может быть последовательным или прямым (произвольным). Требования прямой обработки, используюшей вызов DOS, заключаются в установке требуемого номера записи в соответствующее поле FCB и выдаче команды прямого чтения или записи. Произвольный доступ использует относительный номер записи (байты 33-36) в блоке FCB. Поле имеет размер двойного слова и использует обратную последовательность байт в словах. Для локализации требуемой записи система автоматически пре образует относительный номер записи в номер текущего блока (байты 12-13) и номер текущей записи (байт 32).
ПРЯМОЕ ЧТЕНИЕ Операции открытия и установки DTA одинаковы как для прямой, так и для последовательной обработки. Предположим, что программа должна выполнить прямой доступ к пятой записи файла. Установим значение 05 в поле FCB для относительного номера записи и выполним команды для прямого чтения. В результате успешной операции содержимое пятой записи будет помещено в DTA. Для прямого чтения записи необходимо поместить тре буемое значение относительного номера записи в FCB и вызвать функцию шест.21:
MOV AH,21H ; Запрос на LEA DX,FCBname ; прямое чтение INT 21H ; Вызов DOS
Операция чтения преобразует относительный номер записи в номера текущего блока и записи. Полученные значения исполь зуются для локализации требуемой дисковой записи, передачи содержимого записи в DTA и установки в регистр AL следующие значения:
00 Успешное завершение 01 Данные не доступны 02 Чтение прекращено из-за нехватки места в DTA 03 Прочитана частичная запись, заполненная нулями.
Как видно, среди перечисленных кодов возврата отсутствует состояние конец файла. При корректном чтении записи пред полагается единственный код возврата - 00. Остальные коды возврата могут являться результатом установки неправильного относительного номера записи или некорректная установка адреса DTA или FCB. Так как такие ошибки легко допустить, то полезно выполнять проверку регистра AL на ненулевое зна чение.
Ассемблер для IBM PC. Глава 16. 10
Когда программа выдает первый запрос на прямую запись, операция, используя оглавление для локализации сектора, на котором находится требуемая запись, считывает весь сектор с диска в буфер и пересылает запись в DTA. Предположим, напри мер, что записи имеют размер 128 байт, т.е. четыре записи в одном секторе. Запрос на прямое чтение записи 23 приводит к чтению в буфер четырех записей, лежащих в одном секторе:
| запись 20 | запись 21 | запись 22 | запись 23 |
Когда программа вновь выдаст прямой запрос на запись, например, 23, то операция сначала проверит содержимое буфе ра. Так как данная запись уже находится в буфере, то она непосредственно пересылается в DTA. Если программа запросит запись 35, который нет в буфере, операция через оглавление локализует требуемую запись, считает весь сектор в буфер и поместит запись в DTA. Таким образом, операции прямого дос тупа к записям более эффективны, если номера записей близки друг к другу.
ПРЯМАЯ ЗАПИСЬ Операция создания файла и установки DTA одинаковы как для прямого, так и для последовательного доступа. Для обработки файла учета товаров программа может, используя прямой дос туп, считать необходимую запись, внести, введенные вручную, изменения (например, новое количество товаров) и вернуть запись на диск на то же место. Операция прямой записи использует относительный номер записи в блоке FCB и функцию шест.22 следующим образом:
MOV AH,22H ; Запрос на LEA DX,FCBname ; прямую запись INT 21H ; Вызов DOS
Операция устанавливает в регистре AL следующие коды воз врата:
00 Успешная операция 01 На диске нет места 02 Операция прекращена в результате недостаточ ного места в DTA.
При создании нового файла прямым доступом может быть полу чен ненулевой код возврата. Но при прямом чтении и переписы вании измененных записей на том же месте диска код возврата должен быть только 00. Относительный номер записи в блоке FCB при прямом доступе имеет размер двойного слова (четыре байта), каждое слово за писывается обратной последовательностью байтов. Для неболь ших файлов возможно потребуется установка лишь самого лево го байта или слова, но для больших файлов установка номера записи в трех или в четырех байтах требует некоторой тщательности.
Ассемблер для IBM PC. Глава 16. 11
ПРОГРАММА: ПРЯМОЕ ЧТЕНИЕ ДИСКОВОГО ФАЙЛА ------------------------------------------------------------ На рис.16.3 приведена программа, которая считывает файл, созданный предыдущей программой (см.рис.16.1). Вводя любой относительный номер записи, лежащей в границах файла, поль зователь запрашивает вывод на экран любой записи файла. Если файл содержит 25 записей, то правильными номера являются но мера от 00 до 24. Номер вводится с клавиатуры в ASCII форма те и должен быть в нашем случае одно- или двухзначным чис лом. Программа содержит следующие процедуры:
C10OPEN Открывает файл, устанавливает размер записи 32 и устанавливает адрес DTA. D10RECN Вводит номер записи с клавиатуры, преобразует его в двоичный формат и записывает полученное значение в FCB. В качестве усовершенствования процедуры можно вставить проверку вхождения номера в границы от 00 до 24. F10READ Помещает требуемую запись в DTA в соответствии с относительным номером записи в FCB. G10DISP Выводит запись на экран.
Процедура D10RECN вводит номер записи с клавиатуры и про веряет длину ввода в списке параметров. Возможны три вариан та: 00 Запрошен конец обработки 01 Введено однозначное число (в регистре AL) 02 Введено двухзначное число (в регистре AX)
------------------------------------------------------------ ------------------------------------------------------------ Рис.16.3. Прямое чтение дисковых записей.
Данная процедура преобразует введенное число из ASCII формата в двоичный формат. Так как значение находится в ре гистре AX, то лучше использовать команду AAD для преобра зования. После преобразования двоичный код из регистра AX пересылается в два левых байта поля относительного номера записи в блоке FCB. Если, например, введено число 12 в ASCII формате, то AX будет содержать 3132. Команда AND преобразует это значение в 0102, а команда AAD - в 000C. Результат пре образования заносится в поле относительного номера записи блока FCB в виде С000 0000.
ПРЯМОЙ БЛОЧНЫЙ ДОСТУП ------------------------------------------------------------ Если в программе имеется достаточно места, то одна прямая блочная операция может записать весь файл из DTA на диск, а также прочитать весь файл с диска в DTA. Данная особенность весьма полезна для записи на диск таблиц, которые другие про граммы могут считывать в память для обработки.
Ассемблер для IBM PC. Глава 16. 12
Начать можно с любого правильного относительного номера записи. Число записей также может быть любым, хотя блок дол жен находится в пределах файла. Перед началом необходимо открыть файл и инициализировать DTA. Для операции прямой блочной записи необходимо установить в регистре СX требуемое число записей, установить в FCB стартовый относительный номер записи и выдать функцию шест.28:
MOV AH,28H ; Операция прямой блочной записи MOV CX,records ; Установка числа записей LEA DX,FCBname ; INT 21H ; Вызов DOS
Операция преобразует относительный номер записи в текущие номер блока и номер записи. Полученные значения используются для определения начального адреса на диске. В результате опе рации в регистре AL устанавливаются следующие коды воз врата:
00 Успешное завершение для всех записей 01 На диске недостаточно места.
Кроме того операция устанавливает в FCB в поле относи тельного номера записи и полях текущих номеров блока и запи си значения, соответствующие следующему номеру записи. Напри мер, если были записаны записи с 00 до 24, то следующий номер записи будет 25 (шест.19). Для операции прямого блочного чтения необходимо устано вить в регистре CX требуемое число записей и использовать функцию шест.27:
MOV AH,27H ; Операция прямого блочного чтения MOV CX,records ; Установка числа записей LEA DX,FCBname ; INT 21H ; Вызов DOS
Операция чтения возвращает в регистре AL следующие значе ния: 00 Успешное чтение всех записей 01 Прочитана последняя запись файла 02 Прочитано предельное для DTA число записей 03 Прочитана последняя запись файла не полностью.
В регистре CX остается действительное число прочитанных записей, а в FCB в поле относительного номера записи и полях текущих номеров блока и записи устанавливаются значения, соответствующие следующему номеру записи. Если необходимо загрузить в память весь файл, но число за писей неизвестно, то следует после операции открытия разде лить размер файла на длину записи. Например, для размера файла шест.320 (800) и длине записи шест.20 (32) число запи сей будет шест.19 (25).
Ассемблер для IBM PC. Глава 16. 13
ПРОГРАММА: ПРЯМОЕ БЛОЧНОЕ ЧТЕНИЕ ------------------------------------------------------------ На рис.16.4 приведена программа, выполняющая блочное чте ние файла, созданного программой на рис.16.1. Программа уста навливает начальный относительный номер записи 00, в регист ре CX - счетчик на 25 записей и выводит на экран всю информа цию из DTA (только для того, чтобы убедиться, что информация считана). Другие варианты программы могут включать установ ку другого начального номера записи и считывание менее 25 за писей. В программе организованы следующие процедуры:
E10OPEN Открывает файл, устанавливает размер записи в FCB равным 32 и устанавливает адрес DTA. F10READ Устанавливает число записей равным 25 и выполняет блочное чтение. G10DISP Выводит блок на экран.
Операция чтения преобразует относительный номер записи 00 в FCB в номер текущего блока 00 и номер текущей записи 00. В конце операции чтения в FCB текущий номер записи будет со держать шест.19, а относительный номер записи - шест. 19000000. ------------------------------------------------------------ ------------------------------------------------------------ Рис. 16.4. Прямое блочное чтение.
АБСОЛЮТНЫЕ ОПЕРАЦИИ ДИСКОВОГО ВВОДА-ВЫВОДА ------------------------------------------------------------ Для непосредственного доступа к диску можно использовать операции абсолютного чтения и абсолютной записи с помощью функций DOS INT 25H и 26H. В этом случае не используются оглавление диска и преимущества блокирования и разблокиро вания записей, обеспечиваемые функцией DOS INT 21H. Абсолютные операции предполагают, что все записи имеют размер сектора, поэтому прямой доступ осуществляется к полно му сектору или блоку секторов. Адресация диска выполняется по "логическому номеру записи" (абсолютный сектор). Для определения логического номера записи на двухсторонних дискетах с девятью секторами счет секторов ведется с дорожки 0, сектора 1, следующим образом:
Дорожка Сектор Логический номер записи 0 1 0 0 2 1 1 1 9 1 9 17 2 9 26
Для двухсторонних дискет используется следующая формула:
Логический номер записи = (дорожка х 9) + (сектор - 1)
Ассемблер для IBM PC. Глава 16. 14
Например, логический номер записи на дорожке 2 и секторе 9 определяется как
(2 х 9) + (9 - 1) = 18 + 8 = 26
Фрагмент программы для абсолютных операций ввода-вывода:
MOV AL,drive# ; 0 для A, 1 для B и т.д. MOV BX,addr ; Адрес области ввода-вывода MOV CX,sectors ; Число секторов MOV DX,record# ; Начальный логический номер записи INT 25H или 26H ; Абсолютное чтение или запись
Операции абсолютного чтения или запись разрушают содержи мое всех регистров, кроме сегментных, и устанавливают флаг CF для индикации успешной (0) или безуспешной (1) операции. В случае безуспешной операции содержимое регистра AL описы вает характер ошибки:
AL Причина 1000 0000 Устройство не отвечает 0100 0000 Ошибка установки головок 0010 0000 Ошибка контролера 0001 0000 Ошибка дискеты? 0000 1000 Переполнение DMA при чтении 0000 0100 Сектор не найден 0000 0011 Попытка записи на защищенной дискете 0000 0010 Не найден адресный маркер
Команда INT записывает содержимое флагового регистра в стек. После завершения команды INT следует восстановить флаги, но проверив перед этим флаг CF.
ДРУГИЕ ДИСКОВЫЕ ОПЕРАЦИИ ------------------------------------------------------------ Кроме основных дисковых функций DOS имеется несколько дополнительных полезных дисковых операций.
Сброс диска: Шест. D Обычно нормальное закрытие файла приводит к занесению всех оставшихся в буфере записей на диск и корректировке ог лавления. В особых случаях (между шагами программы или ава рийном завершении) может потребоваться сброс диска. Функция DOS шест. D освобождает все файловые буфера и не корректи рует оглавление диска. Если необходимо, то вначале данная функция закрывает все файлы.
MOV AH,ODH ; Запрос на сброс диска INT 21H ; Вызов DOS
Установка текущего дисковода: Шест. E
Ассемблер для IBM PC. Глава 16. 15
Основное назначение функции DOS шест.E - установка номера текущего (по умолчанию) дисковода. Номер дисковода помещает ся в регистр DL, причем 0 соответствует дисководу A, 1 - B и т.д. MOV AH,OEH ; Запрос на установку MOV DL,02 ; дисковода C INT 21H ; Вызов DOS Операция возвращает в регистр AL число дисководов (незави симо от типа). Так как для DOS необходимо по крайней мере 2 логических дисковода A и B, то DOS возвращает значение 02 и для систем с одним дисководом. (Для определения действитель ного числа дисководов используется команда INT 11H).
Поиск элементов оглавления: шест. 11 и 12 Программной утилите может потребоваться поиск в оглавле нии для доступа к имени файла, например, при удалении или переименовании. Для доступа к первому или единственному элементу оглавления необходимо загрузить в регистр DX адрес неоткрытого блока FCB и выполнить функцию 11H. При использовании расширенного блока FCB можно также получить код атрибута (см.техническое руководство по DOS).
MOV AH,11H ; Запрос на первый элемент LEA DX,FCBname ; Неоткрытый FCB INT 21H ; Вызов DOS
FCB может быть расположено по адресу 5CH в префиксе про граммного сегмента, предшествующем программе в памяти (DTA по умолчанию). Подробно см. гл. 22. В регистре AL операция возвращает шест.FF, если элемент не найден, и шест.00, если найден. Операция устанавливает в DTA номер дисковода (1=A, 2=B и т.д.) имя файла и тип файла. Если найдено несколько элементов при выборке по шаблону (например, *.ASM), то для локализации элементов подмножества директории используется функция 12H:
MOV AH,12H ; Запрос следующего элемента LEA DX,FCBname ; Неоткрытый FCB INT 21H ; Вызов DOS
Коды возврата в регистре AL аналогичны кодам функции 11H.
Удаление файла: шест.13 Для удаления файла в программе используется функция DOS 13H. Операция удаления устанавливает специальный байт в первой позиции имени файла в оглавлении.
MOV AH,13H ; Запрос на удаление файла LEA DX,FCBname ; Неоткрытый FCB INT 21H ; Вызов DOS
Если операция находит и удаляет элемент, то в регистре AL устанавливается код возврата 00, иначе код равен шест.FF.
Ассемблер для IBM PC. Глава 16. 16
Переименование файла: шест. 17 Для переименования файла в программе используется функция DOS шест.17. Старое имя файла записывается в обычном месте блока FCB, а новое - начиная со смещения 16.
MOV AH,17H ; Запрос на переименование LEA DX,FCBname ; Адрес FCB INT 21H ; Вызов DOS
Символы ? и * в новом имени приводят к сохранению в соот ветствующих позициях символов из старого имени. Успешная опе рация устанавливает в регистре AL код возврата 00, а безуспешная (файл по старому имени не найден или по новому имени уже существует) - код FF.
Получение текущего номера дисковода: шест.19 Функция DOS шест. 19 позволяет определить текущий номер дисковода:
MOV AH,19H ; Получить текущий дисковод INT 21H ; Вызов DOS
Операция возвращает шест. номер дисковода в регистре AL (0=A, 1=B и т.д.). Полученное значение можно поместить непосредственно в FCB для доступа к файлу с текущего диско вода. Кроме перечисленных существуют функции для получения информации из таблицы FAT (1B и 10), установки поля прямой записи (24), установки вектора прерываний (25), создания нового программного сегмента (26) и анализа имени файла (29). Эти функции описаны в техническом руководстве по DOS.
ПРОГРАММА: ВЫБОРОЧНОЕ УДАЛЕНИЕ ФАЙЛОВ ------------------------------------------------------------ На рис.16.5 приведена COM-программа по имени SDEL, иллюстрирующая функции DOS 11H, 12H и 13H для удаления выб ранных файлов. Для запроса на удаление файлов пользователь может ввести,например, следующие команды:
SDEL *.* (все файлы) SDEL *.BAK (все BAK-файлы) SDEL TEST.* (все файлы по имени TEST)
Посредством DOS программа определяет в оглавлении элемен ты, удовлетворяющие запросу. DOS заносит полное имя найден ного элемента в PSP (префикс программного сегмента) по смеще нию шест.81 (DTA по умолчанию). Затем программа выводит на экран имя файла и запрос подтверждения. Ответ Y (да) разре шает удаление, N (нет) сохраняет файл, а Return завершает выполнение.
Ассемблер для IBM PC. Глава 16. 17
Обратите внимание на то, что данная программа должна быть создана как COM-программа, так как EXE-программа требуют отличной адресации для использования смещений шест.5С и 81 в PSP. Для тестирования программы используйте скопированные временно файлы. ------------------------------------------------------------ ------------------------------------------------------------ Рис.16.5. Выборочное удаление файлов.
ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ - Программа, использующая INT 21H в базовой версии DOS для операций ввода-вывода на диск, должна содержать блок управления файлом (FCB) для каждого доступного файла. - Один блок содержит 128 записей. Номер текущего блока и номер текущей записи в FCB указывают на дисковую запись, которая должна быть обработана. - В обратной последовательности байт в FCB записываются следующие элементы: номер текущего блока, размер записи, размер файла и относительный номер записи. - Все программы, обрабатывающие один и тот же файл, должны иметь одинаково описанный блок FCB. - Область ввода-вывода (DTA) определяется адресом памяти, куда должна быть помещена запись при чтении или откуда она заносится на диск. Прежде, чем выполнить операцию записи или чтения, в программе необходимо установить каждую область DTA. - Операция открытия файла устанавливает в блоке FCB значе ния для следующих элементов: имя файла, тип файла, размер запи си (шест.80), размер файла и дата. Программа должна заменить размер записей на правильное значение. - Программа, использующая для записи файла операцию DOS INT 21H, должна закрыть файл в конце обработки для того, чтобы поместить на диск все оставшиеся в буфере записи (если таковые имеются) и скорректировать соответствующий элемент оглавления. - При использовании для чтения и записи операции DOS INT 21H система автоматически изменяет текущий номер записи в FCB. - Операция чтения по прерыванию DOS INT 21H проверяет наличие требуемой записи сначала в буфере и при отсутствии выполняет чтение с диска. - Прямой метод доступа требует указания номера записи в поле относительного номера записи блока FCB. - Восемь байт (двойное слово) относительного номера записи кодируются в обратной последовательности байт. - Если требуемая запись при прямом доступе уже находится в буфере, то система передает ее непосредственно в DTA. В противном случае выполняется чтение с диска в буфер всего сектора, содержащего необходимую запись. - Операции прямого блочного чтения и записи более эффек тивны при наличии достаточной памяти. Эти операции особенно удобны для загрузки таблиц.
Ассемблер для IBM PC. Глава 16. 18
- Команды DOS INT 25H и 26H осуществляют дисковые операции абсолютного чтения и записи, но не поддерживают обработку оглавления, не определяют конец файла и не обеспечивают блокирование и деблокирование записей.
ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ 16.1. Напишите функции базовой версии DOS для следующих опе раций: а) создание файла, б) установка DTA, в) после довательная запись, г) открытие файла, д) последова тельное чтение. 16.2. Программа использует размер записи, устанавливаемый при открытии файла по умолчанию. а) Сколько записей содержит один сектор? б) Сколько записей содержит дискета с тремя дорожками по девять секторов на каждой? в) Если на дискете (б) находится один файл, то при последовательном чтении сколько произойдет физических обращений к диску? 16.3. Напишите программу, которая создает дисковый файл, содержащий записи из трех элементов: номер товара (пять символов), наименование товара (12 символов) и стоимость единицы товара (одно слово). Ввод этих значений должен осуществляться пользователем с клавиатуры. Не забудьте преобразовать числа из ASCII представления в двоичное представление. 16.4. Напишите программу, которая выводит на экран файл, созданный в вопросе 16.3. 16.5. Определите текущий блок и запись для следующих номеров записей при прямом доступе: а)45, б)73, в)150, г)260. 16.6. В каком виде номер записи 2652 (десятичное) устанавли вается в поле относительной записи блока FCB? 16.7. Укажите шестнадцатеричные номера функций для следу ющих операций: а) прямая запись, б) прямое чтение, в) прямая блочная запись, г) прямое блочное чтение. 16.8. Напишите команды для определения числа записей файла, предполагая, что операция открытия уже выполнена. Имена полей с размером файла FCB FLSZ и размером записи FCB FCSZ. 16.9. Используя программу из вопроса 16.4 для создания файла с количеством, ценами и наименованиями товаров, сформируйте файл с приведенными ниже данными. Напишите программу, которая выполняет одно блочное чтение данного файла и выводит каждую запись на экран.
Номер Цена Наименование 023 00315 Ассемблеры 024 00430 Компановщики 027 00525 Компиляторы 049 00920 Компрессоры 114 11250 Экстракторы 117 00630 Буксиры
Ассемблер для IBM PC. Глава 16. 19
122 10520 Лифты 124 21335 Процессоры 127 00960 Станки для наклеивания меток 232 05635 Черпатели? 999 00000
16.10. Измените программу из вопроса 16.9 так, чтобы цены записывались на диск в двоичном формате. 16.11. Измените программу из вопроса 16.9 так, чтобы а) ис пользовалась операция прямого чтения, б) пользователь мог вводить номер и количество товара и в) выполня лось вычисление и вывод на экран стоимости (произве дение количества товара на стоимость единицы товара).
Ассемблер для IBM PC. Глава 17. 1