овара. В процессе поиска адрес элементов таблицы номеров должен увеличи ваться на 3, а адрес элементов таблицы цен - на 2. Если сохранить число выполненных циклов при поиске на равно, то, умножив это число на 2 (SHL сдвиг влево на один бит), получим относительный адрес искомого значения цены. (Начальное значение счетчика циклов должно быть равно -1). ъ Помните, что DB позволяет определять значения, не превышающие 256, а DW записывает байты в обратной последовательности. Команды CMP и CMPSW предполагают, что байты в сравниваемых словах имеют обратную последовательность. ъ Если таблица подвергается частым изменениям, или должна быть доступна нескольким программам, то запишите ее на диск. Для внесения изменений в таблицу можно разработать специальную программу модификации. Любые программы могут загружать таблицу с диска и при обновлениях таблицы сами программы не нуждаются в изменениях. ъ Будьте особенно внимательны при кодировке сортирующих программ. Пользуйтесь трассировкой для тестирования, так как малейшая ошибка может привести к непредсказуе мым результатам. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ Ассемблер для IBM PC. Глава 14 34 14.1. Определите таблицу, которая содержит имена дней недели, начиная с воскресения. 14.2 Предполагая, что воскресенье равно 1, напишите команды прямого доступа к таблице, определенной в вопросе 14.1. используйте любые подходящие имена. 14.3 Определите три отдельных связанных таблицы, содержащих следующие данные: а) числовые элементы: 06, 10, 14, 21, 24; б) элементы наименований: видеокассеты, приемники, модемы, клавиатуры, дискеты; в) цены: 93.95, 82.25, 90.67, 85.80, 13.85. 14.4 Составьте программу, позволяющую вводить числовой элемент (ITEMIN) и количество (QTYIN) с клавиатуры. Используя таблицу из вопроса 14.3, разработайте программу табличного поиска элемента равного ITEMIN. Выделите из таблиц наименование и цену. Рассчитайте величину стоимости (Количество х Цена ) и выдайте на экран наименование и стоимость. 14.5 Используя описание таблицы из вопроса 14.3, составьте процедуры: а) пересылающую содержимое одной таблицы в новую (пустую) таблицу; б) сортирующую содержимое новой таблицы в восходящей последовательности. Ассемблер для IBM PC. Глава 15 45 ГЛАВА 15. Дисковая память I: Организация ------------------------------------------------------------ Дисковая память I: Организация Цель: Рассмотреть основные форматы записей в памяти на твердом диске (винчестере) и на дискете, включая оглавление и таблицу распределения файлов. ВВЕДЕНИЕ ------------------------------------------------------------ Диск является распростроненным средством для более или менее долговременного хранения данных. Процессы обработки данных на твердом диске (винчестре) аналогичны процессам для гибких дисков (дискет), за исключением того, что возможно потребуется обеспечить пути для доступа к многочисленным подоглавлениям винчестера. Для обработки файлов полезно ознакомиться с организацией дисковой памяти. Каждая cторона стандартной 5 1/4 дюймовой дискеты содержит 40 концентричес ких дорожек, пронумерованных от 00 до 39. На каждой дорожке форматируется восемь или девять секторов по 512 байтов каждый. Дданные записываются на диск в виде файлов, аналогично тому, как вы записываете ассемблерные программы. Хотя на типы данных, которые можно хранить в файле, не существует каких-либо ограничений, типичный пользовательский файл содержит списки заказчиков, описи товаров и предложений или списки имен и адресов. Каждая запись содержит информацию о конкретном заказчике или описание товара. Внутри файла все записи имеют одинаковую длину и формат. Запись может содержать oдно или несколько полей. Файл заказчиков, например, может состоять из записей, в которые входит номер заказчика, имя заказчика и долговой баланс. Эти записи могут быть расположены в порядке возрастания номеров заказчиков следующим образом: +--+---+-----++--+---+-----++--+---+-----+ +--+---+-----+ |Э1|имя|сумма||Э2|имя|сумма||Э3|имя|сумма|...|Эn|имя|сумма| +--+---+-----++--+---+-----++--+---+-----+ +--+---+-----+ Для программирования дисковых файлов следует в общих чертах ознакомится только с концепцией и терминологией. Если в данной главе размеры диска не указываются, то предполагается диск 5 1/4" формата. ЕМКОСТЬ ДИСКА ------------------------------------------------------------ Емкость гибких дисков: Версия Число Число Число Всего Ассемблер для IBM PC. Глава 15 46 дорожек секторов байтов в на двух на стороне на дорожке секторе сторонах До DOS 2.0 40 8 512 327 680 DOS 2.0 и после 40 9 512 368 640 Высокая плотность 80 15 512 1 228 800 3 1/2" 80 9 512 737 280 Емкость твердых дисков: Версия Число Число Число Всего дорожек секторов байтов в на 4-х на стороне на дорожке секторе сторонах 10 мегабайт 306 17 512 10 653 696 20 мегабайт 614 17 512 21.377.024 Указание стороны (головки), дорожки или сектора на диске осуществляется по номеру. Для стороны и дорожки отсчет ведется с 0, а для сектора - с 1. ОГЛАВЛЕНИЕ ДИСКА (КАТАЛОГ) ------------------------------------------------------------ Для того, чтобы организовать хранение информации на диске, операционная система DOS резервируют определенные сектора для своих нужд. Организация данных на дискете или на твердом диске существенно зависит от их емкости. Формати рованная двухстороняя дискета с девятью сектороми на дорожке содержит следующую системную информацию: Сторона Дорожка Сектор 0 0 1 Запись начальной загрузки 0 0 2-3 Таблица распределения файлов (FAT) 0 0 4-7 Каталог 1 0 1-3 Каталог 1 0 4 ... Файлы данных Область записей данных начинается с третьего сектора на 1-й стороне 0-й дорожки и продолжается до девятого сектора. Следующие записи заносятся на 0-ю сторону 1-й доpожки, затем на 1-ю сторону 1-й дорожки, затем на 0-ю сторону 2-й дорожки и т.д. Такая особенность заполнения дисковой памяти на противоположных дорожках снижает число перемещений головки дисковода. Данный метод используется как для гибких, так и для твердых дисков. При использовании утилиты FORMAT /S для форматизации дискеты, модули DOS IBMBIO.COM и IBMDOS.COM записывается в первые сектора области данных. Ассемблер для IBM PC. Глава 15 47 Все файлы, даже меньшие 512 байт (или кратные 512), начинаются на границе сектора. Для каждого файла DOS создает на нулевой доpожке диска элемент оглавления. Каждый такой элемент описывает имя, дату, размер и расположение файла на диске. Элементы оглавления имеют следующий формат: Байт Назначение 0-7 Имя файла, определяемое из программы, создавшей данный файл. Первый байт может указывать на статус файла: шест.00 обозначает, что данный файл не используется, шест.E5 - файл удален, шест. 2E - элемент подоглавления. 8-10 Тип файла 11 Атрибут файла, определяющий его тип: шест.00 - обычный файл; шест.01 - файл можно только читать; шест.02 - "спрятанный" файл; шест.04 - системный файл DOS; шест.08 - метка тома; шест.10 - подоглавление; шест.20 - архивный файл (для твердого диска). 12-21 Зарезервировано для DOS. 22-23 Время дня, когда файл был создан или последний раз изменялся, в следующим двоичном формате: |чччччммммммссссс| 24-25 Дата создания или последнего изменения файла, сжатая в два слова в следующем двоичном формате: |гггггггм|мммддддд| где год начинается с 1980 и может принимать значения от 0 до 119, месяц - от 1 до 12, а день - от 1 до 31. 26-27 Начальный кластер файла. Относительный номер последних двух секторов каталога. Первый файл данных (без COM-модулей DOS) начинается на относительном кластере 002. Текущая сторона, дорожка и кластер зависят от емкости диска. 28-31 Размер файла в байтах. При создании файла DOS вычисляет и записывает размер файла в это поле. Все поля в каталоге диска, превышающие один байт, записываются в обратной последовательности байтов. ТАБЛИЦА РАСПРЕДЕЛЕНИЯ ФАЙЛОВ ------------------------------------------------------------ Назначение таблицы распределения файлов (FAT - File Allocation Table) - распределение дискового пространства для файлов. Если вы создаете новый файл или изменяете существующий, то DOS меняет элементы таблицы файлов в Ассемблер для IBM PC. Глава 15 48 соответствии с расположением файла на диске. Запись начальной загрузки находится на секторе 1, далее на секторе 2 начинается FAT. FAT содержит элементы для каждого кластера, длина элементов FAT зависит от устройства дисковой памяти. Кластер для односторонних дискет представляет собой один сектор, для двухсторонних дискет - смежную пару секторов. Одно и то же число элементов в FAT определяет в два pаза больше данных для двухсторонних дискет, чем для одностронних. Первые байты FAT определяют тип устройства: FE Односторонняя на 8 секторов FC Односторонняя на 9 секторов FF Двухсторонняя на 8 секторов FD Двухсторонняя на 9 секторов F9 Повышенная емкость (1,2 мегабайта) F8 Твердый диск Второй и третий байты пока содержат FFFF. В следующей таблице показана организация данных для нескольких типов устройств (приведены начальные и конечные номера секторов). Колонка "Кластер" представляет число секторов в кластере: Устройство диска Запись FAT Каталог Кластер нач.загр. Односторонний, 8 секторов 1 2-3 4-7 1 Односторонний, 9 секторов 1 2-5 6-9 1 Двухсторонний, 8 секторов 1 2-3 4-10 2 Двухсторонний, 9 секторов 1 2-5 6-12 2 Повышенная емкость (1,2 М) 1 2-15 16-29 1 Твердый диск XT 1 2-17 18-49 8 Твердый диск AT 1 2-838 4-115 4 Начиная с четвертого байта, элементы FAT определяют сектора. Каждый такой элемент имеет длину 12 битов. (В версии DOS 3 и старше элементы FAT для твердого диска могут иметь длину 16 битов). Два первых элемента FAT, известные как относительные сектора 000 и 001, соответственно, указывают на два последних сектора оглавления, определяя его размер и формат. Первый файл данных начинается на относительном секторе 002. Каждый элемент FAT состоит из трех шест.цифр (12 битов), которые указывают на характер использования конкретного сектора: 000 свободный кластер, nnn относительный номер следующего кластера для файла, FF7 неиспользуемый кластер (сбойная дорожка), FFF последний кластер файла. Предположим, например, что дискета содержит только один файл с именем PAYROLL.ASM, занимающий относительные сектора 002, 003 и 004. Элемент оглавления для этого файла содержит Ассемблер для IBM PC. Глава 15 49 имя файла PAYROLL, тип - ASM, шест.00 для обычного файла, дату создания, 002 - номер первого относительного сектора файла и размер файла в битах. Таблица FAT в этом случае может выглядеть следующим образом (кроме того, что в каждой паре байты в обратной последовательности): Элемент FAT: |FDF|FFF|003|004|FFF|000|000|...|000| Относительн.сектор: 0 1 2 3 4 5 6 ...конец Первые два элемента FAT указывают расположение каталога на относительных секторах 000 и 001. Для ввода рассматриваемого файла в память, система выполняет следующие действия: 1. DOS получает доступ к дискете и ищет в каталоге имя PAYROLL и тип ASM. 2. Затем DOS определяет по каталогу положение первого относительного сектора файла (002) и загружает содержи мое этого сектора в буферную область в основной памяти. 3. Номер второго сектора DOS получает из элемента FAT, соответствующего относительному сектору 002. Из диаграммы, приведенной выше, видно, что зтот элемент содержит 003. Это обозначает, что файл продолжается в относительном секторе 003. DOS загружает содержимое этого сектора в буфер в основной памяти. 4. Номер третьего сектора DOS получает из элемента FAT, соответствующего относительному сектору 003. Этот элемент содержит 004, значит файл продолжается в относительном секторе 004. DOS загружает срдержимое этого сектора в буфер в основной памяти. 5. Элемент FAT для относительного сектора 004 содержит шест.FFF, что свидетельствует о том, что больше нет данных для этого файла. Элемент каталога содержит номер начального кластера для каждого файла, а FAT - шест.трехзначные элементы, указываю щие на расположение каждого дополнительного кластера, если он имеется. Для того, чтобы указать, например, что файл содержит все записи только в первом кластере, таблица FAT должна содержать шест.FFF в элементе, представляющем первый относительный кластер. В качестве простого примера рассмотрим элемент каталога, указывающий, что некоторый файл начинается в относительном кластере 15. Для локализации первого элемента таблицы FAT необходимо: ъ Умножить 15 на 1,5, получим 22,5. ъ Выполнить выборку содержимого байтов 22 и 23 из FAT. Прежположим, что они содержат F*FF. ъ Переставить байты: FFF*. Ассемблер для IBM PC. Глава 15 50 ъ Так как номер 15-нечетный, то первые три цифры - FFF указывают на отсутствие других кластеров для данного файла. Теперь рассмотрим файл, который занимает четыре кластера, начинающихся с номера 15. Таблица FAT, начиная с байта 22 и далее, в этот pаз показана в правильной обратной последовательности байтов в паpах: 6* 01 17 80 01 FF*F Для того, чтобы найти первый элемент FAT, необходимо умножить 15 на 1,5, получим 22,5, и выбрать содержимое байтов 22 и 23, как в предыдущем примере. В этот раз эти байты содержат 6*01, что после перестановки байт даст 016*. Так как 15-число нечетное, то используются первые три цифры 016. Второй кластер для файла, следовательно, имеет номер 016. Для того, чтобы найти третий кластер, необходимо умножить 16 на 1,5 получим 24. Затем следует выбрать содержимое байтов 24 и 25 таблицы FAT. Значение 1780 после перестановки байтов даст 8017. Так как число 16 четное, то используются последние три цифры 017. Третий кластер для файла имеет номер 017. Для того, чтобы найти четвертый кластер, необходимо умножить 17 на 1,5, получим 25.5. Затем следует выбрать содержимое байтов 25 и 26 таблицы FAT. Значение 8001 после перестановки байтов даст 0180. Так как число 17 нечетное, то используются первые три цифры 018. Четвертый кластер для файла имеет номер 018. При использовании этой же процедуры для локализации содержимого следующего элемента FAT по относительным адресам 27 и 28, получим FF*F, что после перестановки даст *FFF. Так как число 18 четное, используются последние три цифры FFF, что обозначает последний элемент. Как было ранее сказано, все файлы начинаются на границе кластеpа. Кроме того, совсем не обязательно файл должен храниться в соседних кластерах, он может быть разбросан на диске по разным секторам. Если в программе необходимо определить тип установленного диска, то можно обратиться к таблице FAT непосредственно, или, что предпочтительней, использовать функцию DOS 1BH или 1CH. ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ ъ Независимо от размеров все файлы начинаются на границе кластера. ъ Оглавление (каталог) содержит для каждого файл на диске элементы, определяющие имя, тип, атрибуты, дату, началь ный сектор и pазмер файла. Ассемблер для IBM PC. Глава 15 51 ъ Таблица распределения файлов (FAT) содержит один элемент для каждого кластеpа в каждом файле. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ 15.1. Какую длину в байтах имеет стандартный сектор? 15.2. Где расположена запись начальной загрузки? 15.3. Как обозначаются в оглавлении удаленные файлы? 15.4. Какие дополнительные действия выполняются при формати зации дискеты по команде DOS FORMAT /S? 15.5. Где и каким образом обозначается в таблице FAT, что устройством является твердый диск? 15.6. Имеется файл размером 2890 (десятичное) байтов: а) Где хранит cистема размер файла? б) Как выражается этот размер в шестнадцатиричном формате? в) Покажите значе ние в том виде, как оно записывается системой. Ассемблер для IBM PC. Глава 16. 1 ГЛАВА 16. Дисковая память 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 Прочитана частичная запись, заполненная нулями. Как видно, среди перечисленных кодов возврата отсутствует состояние конец файла. При корректном чтении записи пред полагается единственны