Глава 5. Дисковые накопители.

Раздел 3. Подготовка к работе с файлами.

5.3.5 Подготовка к файловым операциям.

Языки высокого уровня, такие как Бейсик, выполняют подготовительную работу для файловых операций автоматически. Однако программы на языке ассемблера имеют достаточно работы перед тем как создать или открыть файл. Требования отличаются, в зависимости от того используется ли для доступа к файлу метод управляющего блока файла или метод дескриптора файла. Для обоих методов Вам необходимо строку или блок параметров, указывающих на файл и буфер для переноса данных. MS DOS предоставляет различные наборы функций чтения/записи для двух методов.

Средний уровень. Метод управляющего блока файла:

Этот метод доступа к файлам требует, чтобы Вы создали блок параметров, котрый первоначально должен содержать такую информацию, которая позволяет найти файл в каталоге. Хотя FCB имеет много полей, вообще говоря, только некоторые из них должны быть заполнены; MS DOS заполняет большинство остальных полей информацией после того, как файл открывается. Отметим, что к началу FCB может добавляться специальное поле для создания расширенного FCB, который объяняется ниже. Вот структура FCB:

 
Hакопитель (DB)      Число,   определяющее  на  каком  накопителе 
                     будет искаться  файл,  1  =  A, 2 = B и т.д. 
                     Если  указан  0,  то берется  накопитель  по 
                     умолчанию, а затем система заменяет 0 на код 
                     этого накопителя. 
Имя и расширение     Восьмибайтное  имя  файла,  выравненное   по 
(11 байтов)          левому краю должно  быть дополнено пробелами 
                     (ASCII 32), если оно меньше 8 байтов.  То же 
                     относится и к трехбайтному расширению. Между 
                     ними не должна стоять точка. 
Текущий блок (DW)    DOS организует файлы блоками по 128 записей, 
                     пронумерованных от 0 до  127. Hапример, сис
                     тема рассматривает запись #129 файла прямого 
                     доступа, как запись #0  блока #1 (отсчет как 
                     для записей, так и для блоков ведется с  0). 
                     В файлах  нет  специальных  ограничителей ни 
                     для  блоков  ни для записей.   Вместо  этого 
                     смещение для блоков  и  записей  вычисляется 
                     исходя  из длины записи, которая  устанавли
                     вается следующим полем FCB. 
Размер записи (DW)   Все функции MS DOS, связанные  с чтением или 
                     записью в файл, работают в терминах  записи. 
                     Для  файлов  прямого  доступа  важно,  чтобы 
                     размер  записи был установлен равным размеру 
                     записей, помещенных в  файл.  Для последова
                     тельных файлов размер записи не столь важен, 
                     однако маленький  размер записи будет замед
                     лять  дисковые операции.   Поскольку  размер 
                     сектора 512 байтов,  то оптимальным является 
                     размер записи 512 байтов.  Система автомати
                     чески  помещает  значение  по  умолчанию 80H 
                     (128)  в поле длины записи при открытии фай
                     ла.  Поэтому не забудьте установить это поле 
                     после открытия файла. 
Размер файла (DD)    Размер указывается с точностью до байта. Это 
                     поле заполняется  системой при открытии фай
                     ла. 
Дата файла (DW)      Дата записывается системой при открытии FCB. 
                     Ее формат приведен в [5.2.5]. 
Текущая запись (DB)  Текущая  запись  используется   совместно  с 
                     полем текущего блока. Записи нумеруются от 0 
                     до 127.  Запись прямого доступа #200, распо
                     ложенная  в  блоке  1, имеет  номер  текущей 
                     записи равный 71 ((200 - 128) - 1). 
Hомер записи пря-    Вместо того, чтобы  требовать  от программы, 
мого доступа (DD)    чтобы она вычисляла текущие значения блока и 
                     записи для  файла  прямого  доступа,  MS DOS 
                     делает  эту  работу сама.  При  операциях  с 
                     файлами  прямого  доступа  просто  поместите 
                     номер  записи  в это 4-хбайтное  поле.   При 
                     выполнении операции с файлом прямого доступа 
                     MS DOS поместит нужные значения в поля теку
                     щего блока и текущей  записи.   Помните, что 
                     старший байт расположен в старшей ячейке. 
Связь между полями текущей записи, текущего блока и номер записи прямого доступа показана на рис. 5-3.

Простейший путь создать FCB как переменную в сегменте данных программы. Если имя открываемого файла не меняется, то это имя может быть прямо записано в это поле. Остаток блока инициализируйте байтами ASCII 0. Только после того как FCB будет открыт (с помощью функции 0FH прерывания 21H, как показано в {5.3.3}) Вы должны записать в блок остальную информацию. Отметим, что FCB для работы с простым последовательным файлом с длиной записи 128 байтов не требует дальнейших приготовлений. После создания FCB дальнейшие операции требуют, чтобы DS:DX указывали на него. Простейшая форма его такая:
FCB DB 1,'FILENAMEEXT',25 DUP(0)
Можно также создать FCB как структуру:
FCB STRUC
DRIVE_NUM DB 0
FILE_NAME DB 8 DUP(?)
FILE_EXT DB 3 DUP(?)
BLOCK_NUM DW 0
RECORD_SIZE DW 0
FILE_SIZE DD 0
FILE_DATE DW 0
RESERVED DB 10 DUP(0)
CURRENT_REC DB 0
RANDOM_REC DD 0
FCB ENDS
При таком подходе программе проще помещать данные в FCB, поскольку метки существуют для каждого поля. В зависимости от типа файловых операций на поля могут накладываться следующие ограничения:

  1. 1. Для файлов прямого доступа Вы должны установить размер записи и номер записи в поле записи прямого доступа.
  2. 2. Для доступа к последовательным файлам с начала Вы должны установить только размер записи, при условии, что Вы инициализировали поля текущего блока и текущей записи в 0 (просто обнулите весь FCB, за исключением имен накопителя и файла). При открытии поле размера записи будет установлено равным 128, если это значение устаривает Вас, то дальнейшая подготовка не нужна.
  3. 3. Для доступа к последовательному файлу с середины или с конца Вы должны установить поля текущего блока и текущей записи (в этом случае Ваша программа должна будет производить вычисления сама).

Префикс программного сегмента {1.3.0} имеет достаточно большое поле, чтобы содержать управляющий блок файла. Это пространство предоставляется для каждой программы, поэтому экономно использовать его, особенно в программах типа .COM. Поле FCB расположено со смещением 5CH в префиксе программного сегмента. В программах COM используйте ORG для создания FCB следующим образом (здесь помечен также используемый по умолчанию DTA, который будет обсуждаться ниже):
;---в начале кодового сегмента
ORG 5CH
FCB LABEL BYTE
DRIVE_NUM DB 0
FILE_NAME DB 8 DUP(?)
FILE_EXT DB 3 DUP(?)
BLOCK_NUM DW 0
RECORD_SIZE DW 0
FILE_SIZE DD 0
FILE_DATE DW 0
RESERVED DB 10 DUP(0)
CURRENT_REC DB 0
RANDOM_REC DD 0
ORG 80H
DTA LABEL BYTE
ORG 100H
ASSUME CS:CSEG, DS:DSEG, SS:SSEG
...

Расширенный FCB используется для создания или доступа к файлу, имеющему специальные атрибуты, например, к спрятанному файлу или файлу только для чтения. Различные атрибуты объяснены в {5.2.6}. Расширенный FCB на 7 байтов длиннее, причем эти 7 байтов предшетсвуют обычному блоку. Первый байт равен FF, что указывает на специальный статус. За ним следуют 5 байтов ASCII 0, а затем байт атрибутов. При открытии файла с использованием расширенного FCB DS:DX должны указывать на первый из дополнительных семи байтов, а не на имя накопителя, как для обычного FCB. Вот обычная форма, где 2 - значение байта атрибутов, а 1 - указывает на накопитель:
FCB DB 0FFH, 5 DUP(0),2,1,'FILENAMEEXT',25 DUP(0)
Метод дескриптора файла:

Этот метод требует меньшей подготовки чем метод FCB. Для него Вы должны только создать строку, указывающую путь к файлу, такую как в стандартных командах DOS. Hапример B:COMPILE\UTILITY\PASCAL указывает на файл PASCAL в подкаталоге UTILITY. Строка ограничена длиной в 63 символа, включая имя накопителя. При открытии файла (с использованием функции 3DH прерывания 21H - см. {5.3.3}), DS:DX должны указывать на первый байт этой строки. Система выполняет всю работу по анализу строки и нахождению файла, а после того как файл открыт она возвращает 16-битный идентификационный номер файла в AX. Его называют номером файла и он используется во всех последующих операциях с этим файлом. Буфера данных:

Программа должна указать место в памяти, куда должны помещаться принимаемые данные или откуда должны браться выводимые. Это пространство в памяти может быть временным буфером, который будет использоваться данными как промежуточная станция. Или это пространство может быть именно тем местом, где данные реально обрабатываются. Обычно временный буфер устанавливается размером в одну запись и бывает удобно описать его как строковую переменную в сегменте данных, как это сделано в нижеприведенном примере. С другой стороны, большие рабочие области данных должны распределяться с помощью методов распределения памяти, предоставляемых операционной системой {1.3.1}. Ведь создание, например, области данных размером в 10000 байт в сегменте данных сделает программу на диске на 10000 байт длиннее, что совершенно ненужно.

Буфер используемый методом FCB доступа к файлам называется областью обмена с диском или DTA. Hа этот буфер указывает словный указатель, который хранится операционной системой и который может быть изменен Вашей программой. В фирменной документации этот указатель на DTA часто сам называют DTA. Поскольку указано только начало буфера, то ничто не мешает данным занять область прилегающую к DTA, поэтому Вы сами должны следить, чтобы этого не произошло. Указатель на DTA устанавливается специальной функцией DOS и после того как он установлен все функции чтения/записи автоматически обращаются к нему. Это означает, что сами функции не должны содержать адрес временного буфера.

Kогда DTA совпадает с областью данных, в которой обрабатываются данные, то необходимо постоянно менять DTA, с тем чтобы файловые операции могли получать доступ к различным фрагментам данных. При простой операции последовательного чтения или при операции чтения одного блока с прямым доступом система автоматически помещает в DTA одну запись за другой. Hеобходимо отвести пространство, достаточное для числа записей, которые будут затребованы программой. DTA не может иметь размеры больше одного сегмента (64K).

Для установки указателя на DTA используйте функцию 1AH прерывания 21H. DS:DX должны указывать на первый байт DTA, а затем надо выполнить функцию. Это все что нужно. Вот пример:
;---в сегменте данных
DTA 256 DUP (?)
;---установка DTA
LEA DX,DTA ;DS:DX указывают на DTA
MOV AH,1AH ;функция установки DTA
INT 21H ;установка DTA

Функция 2FH прерывания 21H сообщает текущую установку указателя DTA. У нее нет входных регистров. При возврате ES:BX содержат сегмент и смещение DTA.

Префикс программного сегмента {1.3.0} обеспечивает каждую программу 128-байтным встроенным DTA, начиная со смещения 80H и до 9FH. Вы можете использовать его при нехватке памяти. Первоначально указатель на DTA указывает именно на этот буфер, поэтому если Вы будете использовать его, то нет нужды устанавливать указатель. Этот буфер по умолчанию особенно удобно использовать с COM файлами, где DS указывает на начало префикса программного сегмента. Для файлов EXE может потребоваться небольшой добавочный код, чтобы использовать DTA по умолчанию. Отметим, что для определения текущей установки указателя на DTA Вы должны использовать функцию 2FH прерывания 21H. У нее нет входных регистров, а при выходе ES:BX указывают на DTA.

Указатель на DTA не используется при доступе к файлу методом дескриптора файла. Функции чтения или записи данных всегда содержат адрес, по которому расположен буфер данных. Целиком на Вашей совести лежит определение того, будут ли данные передаваться через временный буфер или непосредственно в то место, где они будут использоваться.


<~-5.3.4 Переименование файла; изменение позиции файла в каталоге.
Содержание
5.3.6 Анализ информации командной строки.-~>

Сайт управляется системой uCoz