Assembler для начинающих


Блок управления файлом (FCB)



Блок управления файлом (FCB)


    Прежде, чем перейти к упомянутому примеру, необходимо рассмотреть
    формируемую DOS структуру данных - блок управления файлом FCB (File
    Control Block), который является существенным элементом файловой
    системы и участвует во всех файловых операциях.
 
      Блок управления файлом обеспечивает связь пользовательской
    программы с функциями DOS. При любой файловой операции происходит
    обращение к блоку FCB. На Фиг.5.5 показан состав стандартного
    блока FCB. Имеется модификация блока FCB, называемая расширенным
    блоком FCB, которая применяется в специальных случаях, когда нужно
    "скрыть" файл. Скрытый файл защищен от записи. Это значит, что
    программа не может модифицировать содержимое этого файла, не


    изменив предварительно его блока FCB. Скрытый файл не фигурирует в
    листинге справочника. Скрыть файл - один из простейших способов
    защиты файла от неумелого пользователя. В приводимых примерах
    используются только стандартные блоки FCB.
 
      Поля данных блока FCB охватывают все атрибуты файла. Номер
    дисковода, имя и тип файла составляют идентификатор файла. Размер
    файла и дата яаляются атрибутами файла, которые приводятся в
    листинге справочника. Оставшиеся поля - текущий номер блока, длина
    записи и номер записи при произвольном доступе - служат для
    определения местоположения внутри файла при операциях чтения и
    записи. Длина записи указывает на число байтов в определяемой
    пользователем записи. Так как все операции чтения и записи в файл
    начинаются с границы записи, то длина записи определяет количество
    данных, обрабатываемых во время каждой из этих операций.
      Существуют два способа определения текущей записи при обращении
    к файлу. При первом, последовательном, способе записи
    обрабатываются по порядку. При этом текущий номер блока и
    относительный номер записи определяют запись, которая будет
    обрабатываться следующей. По мере того, как программа выполняет
    операции чтения или записи, DOS увеличивает на 1 относительный
    номер записи, чтобы он указывал на следующую запись. Выполнение

            ЪДДДДї
          0 і    і                                          Номер носителя
            ГДДДДЕДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДї
          1 і    і      і    і        і    і    і     і    і           Имя файла
            ГДДДДЕДДДДЕДДДДЕДДДДБДДДДБДДДДБДДДДБДДДДЩ
          9 і    і      і    і                                    Расширение
            ГДДДДЕДДДДЕДДДДЩ
         0С і    і      і                                   Текущий блок
            ГДДДДЕДДДДґ
         0E і    і      і                                   Размер записи
            ГДДДДЕДДДДЕДДДДВДДДДї
         10 і    і      і    і        і                           Размер файла
            ГДДДДЕДДДДЕДДДДБДДДДЩ
         14 і    і      і                                   Дата
            ГДДДДЕДДДДЕДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДДї
         16 і    і      і    і        і    і    і     і    і    і      і    Зарезервировано
            ГДДДДЕДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДДЩ
         20 і    і                                          Относительная запись
            ГДДДДЕДДДДВДДДДВДДДДї                            (нумерация в блоке)
         21 і    і      і    і        і                           Номер записи
            АДДДДБДДДДБДДДДБДДДДЩ                            прямого доступа

               Фиг. 5.5 Блок управления файлом
 
    последовательных операций идет в направлении от начала к концу
    файла. Примером последовательного файла служит программный файл на
    языке ассемблера. Ассемблер осуществляет чтение записей от начала
    до конца этого файла.
 
      Программа может обращаться к файлу, используя также и
    произвольный доступ. Произвольный в данном случае не означает, что
    запись выбирается случайным образом. Наоборот, это значит, что
    программа может выбрать в качестве следующей любую запись в файле.
    По-другому такой файл называют файлом с прямым доступом, так как у
    программы имеется непосредственный доступ к любой записи.
 
      Программа может обращаться к файлу любым из двух указанных
    способов. При последовательных операциях DOS автоматически изменяет
    в блоке FCB значение поля относительного номера записи. При
    произвольном доступе к файлу номер записи должен определяться
    программой. В файловой системе файл с произвольным доступом
    является аналогом вектора. Точно так же, как для обращения к любому
    элементу вектора программа должна задать значение соответствующего
    индекса, так и при обращение к записи в файле с произвольным
    доступом номер записи должен определяться программой.
 
      Теперь можно рассмотреть пример программы, использующей блок
    FCB и функции DOS. На Фиг. 5.6 приведена длинная программа, которая
    реально мало что делает. Ее цель - продемонстрировать использование
    блока FCB и функци DOS, связанных с прерыванием 21H. Однако
    содержащиеся в этой программе операции могут применяться в реальных
    задачах.
            Microsoft (R) Macro Assembler Version 5.00              1/1/80 04:02:12
            Фиг. 5.6 Пример использования функций ДОС               Page         1-1
 
 
                                          PAGE    ,132
                                          TITLE   Фиг. 5.6 Пример использования функций ДОС
             0000                   CODE    SEGMENT
             005C                         ORG     05CH                        ; Положение первого поля FCB
             005C                   FCB               LABEL   BYTE            ; Метка всего поля FCB
             005C  ??               FCB_DRIVE         DB      ?         ; Номер устройства
             005D  0008[                  FCB_NAME                DB      8 DUP (?)       ; Имя файла
                    ??
                               ]
             0065  0003[                  FCB_EXT                 DB      3 DUP (?)       ; Тип файла
                    ??
                               ]
 
             0068  ????             FCB_BLOCK         DW      ?         ; Номер текущего блока
             006A  ????             FCB_RECORD_SIZE         DW      ?         ; Размер записи
             006C  ????????               FCB_FILE_SIZE           DD      ?         ; Размер файла
             0070  ????             FCB_DATE                DW      ?         ; Дата последнего изменения
             0072  000A[                  FCB_RESV                DB      10 DUP (?)      ; Зарезервировано ДОС
                    ??
                               ]
             007C  ??               FCB_CURRENT_RECORD      DB      ?       ; Номер текущей записи
             007D  ????????               FCB_RANDOM_RECORD       DD      ?       ; Номер записи при прямом
                                                                  ;  доступе
             0090                         ORG     090H
             0090                   DISK_TRANSFER_ADDRESS   LABEL   BYTE    ; Буфер для данных
 
             0100                         ORG     100H
                                          ASSUME  CS:CODE,DS:CODE,ES:CODE
             0100  E9 01CD R                    JMP     PROGRAM_START         ; Переход на начало программы
 
             = 0020                       RECORD_SIZE     EQU     32          ; Размер записи
             0103  03 00 00 00 00         KEYBOARD_BUFFER DB      3, 0, 0, 0, 0   ; Буфер ввода с клавиатуры
             0108  94 A0 A9 AB 20 E3 A6     FILE_ERROR_MSG  DB      'Файл уже существует', 10, 13, '$'
                 A5 20 E1 E3 E9 A5 E1
                 E2 A2 E3 A5 E2 0A 0D
                 24
             011E  8D A5 A2 AE A7 AC AE     BAD_OPEN_MSG    DB      'Невозможно открыть файл', 10, 13, '$'
                 A6 AD AE 20 AE E2 AA
                 E0 EB E2 EC 20 E4 A0
                 A9 AB 0A 0D 24
             0138  8E E8 A8 A1 AA A0 20     BAD_WRITE_MSG   DB      'Ошибка при записи в файл', 10, 13, '$'
                 AF E0 A8 20 A7 A0 AF
                 A8 E1 A8 20 A2 20 E4
                 A0 A9 AB 0A 0D 24
             0153  8E E8 A8 A1 AA A0 20     BAD_READ_MSG    DB      'Ошибка при чтении файла', 10, 13, '$'
                 AF E0 A8 20 E7 E2 A5
                 AD A8 A8 20 E4 A0 A9
                 AB A0 0A 0D 24
             016D  8E E8 A8 A1 AA A0 20     BAD_CLOSE_MSG   DB      'Ошибка при закрытии файла', 10, 13, '$'
 
                     Фиг. 5.6 Пример использования функциямй DOS (начало)
                 AF E0 A8 20 A7 A0 AA
                 E0 EB E2 A8 A8 20 E4
                 A0 A9 AB A0 0A 0D 24
 
             0189  8F E0 A8 20 A2 A2 AE     INPUT_BAD_MSG   DB      'При вводе требуется два символа', 10, 13, '$'
                 A4 A5 20 E2 E0 A5 A1
                 E3 A5 E2 E1 EF 20 A4
                 A2 A0 20 E1 A8 AC A2
                 AE AB A0 0A 0D 24
             01AB  82 A2 AE A4 20 A4 AE     CHAR_BAD_MSG    DB      'Ввод должен быть: символ|символ', 10, 13, '$'
                 AB A6 A5 AD 20 A1 EB
                 E2 EC 3A 20 E1 A8 AC
                 A2 AE AB 7C E1 A8 AC
                 A2 AE AB 0A 0D 24
 
                                    ;-----   Установка буфера (Области связи с диском)
 
             01CD                   PROGRAM_START:
             01CD  B4 1A                        MOV     AH, 1AH               ; Установка буфера
             01CF  8D 16 0090 R                 LEA     DX, DISK_TRANSFER_ADDRESS
             01D3  CD 21                        INT     21H
 
                                    ;-----   Поиск файла
 
             01D5  B4 11                        MOV     AH, 11H               ; Поиск файла с заданным
             01D7  8D 16 005C R                 LEA     DX, FCB               ;  именем
             01DB  CD 21                        INT     21H
             01DD  0A C0                        OR      AL, AL
             01DF  75 0A                        JNZ     NO_FILE               ; Переход если файл новый
             01E1  8D 16 0108 R                 LEA     DX, FILE_ERROR_MSG      ; Сообщение о неправильном
             01E5                   ERROR_EXIT:                   ; имени файла
             01E5  B4 09                        MOV     AH, 9H                ; Вывод сообщения на экран
             01E7  CD 21                        INT     21H             ;  и выход из программы
             01E9  CD 20                        INT     20H
 
                                    ;-----   Создание нового файла
             01EB                   NO_FILE:
             01EB  B4 16                        MOV     AH, 16H               ; Создание файла
             01ED  8D 16 005C R                 LEA     DX, FCB
             01F1  CD 21                        INT     21H
             01F3  0A C0                        OR      AL, AL                ; Проверка на успех
             01F5  74 06                        JZ      CREATE_OK
             01F7  8D 16 011E R                 LEA     DX, BAD_OPEN_MSG            ; Сообщение об ошибке при
             01FB  EB E8                        JMP     ERROR_EXIT            ;  создании файла
 
                                    ;-----  Установка параметров FCB
             01FD                   CREATE_OK:
             01FD  C6 06 007C R 00              MOV     FCB_CURRENT_RECORD, 0       ; Инициализация номера
             0202  C7 06 007D R 0000                  MOV     WORD PTR FCB_RANDOM_RECORD, 0   ;  записи
             0208  C7 06 007F R 0000                  MOV     WORD PTR FCB_RANDOM_RECORD+2, 0
             020E  C7 06 006A R 0020                  MOV     WORD PTR FCB_RECORD_SIZE, RECORD_SIZE
 
                     Фиг. 5.6 Пример использования функциямй DOS (продолжение)
                                    ;-----   Вывод в файл
 
             0214  B0 41                        MOV     AL, 'A'                 ; В этом цикле выводятся
             0216                   CHARACTER_LOOP:                     ; символы алфавита
 
             0216  8D 3E 0090 R                 LEA     DI, DISK_TRANSFER_ADDRESS
             021A  B9 0020                      MOV     CX, RECORD_SIZE
             021D  F3/ AA                       REP     STOSB                 ; Заполнение буфера символами
             021F  50                     PUSH    AX              ; Сохранение символа
             0220  8D 16 005C R                 LEA     DX, FCB
             0224  B4 15                        MOV     AH, 15H               ; Последовательный вывод
             0226  CD 21                        INT     21H             ;  блока символов
             0228  0A C0                        OR      AL, AL                ; Проверка на ошибку
             022A  58                     POP     AX              ; Восстановление символа
             022B  74 06                        JZ      WRITE_OK
             022D  8D 16 0138 R                 LEA     DX, BAD_WRITE_MSG       ; Ошибка записи
             0231  EB B2                        JMP     ERROR_EXIT
             0233                   WRITE_OK:
             0233  FE C0                        INC     AL              ; Следующий символ
             0235  3C 5B                        CMP     AL, 'Z'+1               ; Проверка на окончание вывода
             0237  75 DD                        JNE     CHARACTER_LOOP        ; Вывод следующего символа
 
                                    ;-----  Изменение файла
             0239                   KEYBOARD_LOOP:                      ; Цикл ввода символов
             0239  8D 16 0103 R                 LEA     DX, KEYBOARD_BUFFER     ;  с клавиатуры и
             023D  B4 0A                        MOV     AH, 0AH               ;  изменение файла
             023F  CD 21                        INT     21H             ; Ввод с клавиатуры
             0241  80 3E 0104 R 02              CMP     KEYBOARD_BUFFER+1, 2    ; Было введено два символа?
             0246  74 0A                        JE      KEY_INPUT_OK
             0248  8D 16 0189 R                 LEA     DX, INPUT_BAD_MSG       ; Сообщение об ошибке
             024C                   KEYBOARD_ERROR:
             024C  B4 09                        MOV     AH, 9H
             024E  CD 21                        INT     21H             ; Печать сообщения об ошибке
             0250  EB E7                        JMP     KEYBOARD_LOOP         ; Повторный ввод
             0252                   KEY_INPUT_OK:
             0252  8D 16 01AB R                 LEA     DX, CHAR_BAD_MSG            ; Установка указателя на
                                                                  ;  сообщение об ошибке
             0256  A0 0105 R                    MOV     AL, KEYBOARD_BUFFER+2   ; Выборка первого символа
             0259  3C 24                        CMP     AL, '$'                 ; Сравнение с символом конца
             025B  75 03                        JNE     CHANGE_RECORD         ; Изменение записи
             025D  EB 5C 90                     JMP     PROGRAM_EXIT
 
                                    ;-----  Чтение старой записи из файла
             0260                   CHANGE_RECORD:
             0260  3C 41                        CMP     AL, 'A'                 ; Проверка на то, что символ
             0262  7C E8                        JL      KEYBOARD_ERROR        ;  находится в диапазоне A-Z
             0264  3C 5A                        CMP     AL, 'Z'
             0266  77 E4                        JA      KEYBOARD_ERROR
             0268  2A E4                        SUB     AH, AH                ; Преобразование символа в
             026A  2C 41                        SUB     AL, 'A'                 ;  номер записи
             026C  A3 007D R                    MOV     word ptr FCB_RANDOM_RECORD, AX  ; Занесение номера в FCB
             026F  8D 16 005C R                 LEA     DX, FCB
             0273  B4 21                        MOV     AH, 21H               ; Прямое чтение записи
             0275  CD 21                        INT     21H
 
                     Фиг. 5.6 Пример использования функциямй DOS (продолжение)
             0277  0A C0                        OR      AL, AL                ; Проверка на ошибку
             0279  74 07                        JE      RANDOM_RECORD_OK
             027B  8D 16 0153 R                 LEA     DX, BAD_READ_MSG            ; Сообщение об ошибке
 
             027F  E9 01E5 R                    JMP     ERROR_EXIT
 
                                    ;-----  Вывод старой записи на экран
 
             0282                   RANDOM_RECORD_OK:
             0282  C6 06 00B0 R 0A              MOV     DISK_TRANSFER_ADDRESS+32, 10    ; Занесение символов конца
             0287  C6 06 00B1 R 0D              MOV     DISK_TRANSFER_ADDRESS+33, 13    ;  строки и конца вывода
             028C  C6 06 00B2 R 24              MOV     DISK_TRANSFER_ADDRESS+34, '$'   ;  в буфер
             0291  B4 09                        MOV     AH, 9H
             0293  8D 16 0090 R                 LEA     DX, DISK_TRANSFER_ADDRESS
             0297  CD 21                        INT     21H             ; Вывод записи на экран
 
                                    ;-----  Изменение файла
 
             0299  A0 0106 R                    MOV     AL, KEYBOARD_BUFFER+3   ; Выборка символа, на который будет
             029C  B9 001F                      MOV     CX, RECORD_SIZE-1       ;  заменяться содержимое записи
             029F  8D 3E 0091 R                 LEA     DI, DISK_TRANSFER_ADDRESS+1
             02A3  F3/ AA                       REP     STOSB                 ; Замена 31 символа
             02A5  B4 22                        MOV     AH, 22H
             02A7  8D 16 005C R                 LEA     DX, FCB
             02AB  CD 21                        INT     21H             ; Прямая запись на файла на
                                                                  ;  старое место
             02AD  0A C0                        OR      AL, AL                ; Проверка на ошибку
             02AF  74 07                        JZ      RANDOM_WRITE_OK
             02B1  8D 16 0138 R                 LEA     DX, BAD_WRITE_MSG       ; Сообщение об ошибке
             02B5  E9 01E5 R                    JMP     ERROR_EXIT
             02B8                   RANDOM_WRITE_OK:
             02B8  E9 0239 R                    JMP     KEYBOARD_LOOP         ; Обработка следующей записи
 
                                    ;-----  Конец программы
 
             02BB                   PROGRAM_EXIT:
             02BB  B4 10                        MOV     AH, 10H               ; Закрытие файла
             02BD  8D 16 005C R                 LEA     DX, FCB
             02C1  CD 21                        INT     21H
             02C3  0A C0                        OR      AL, AL                ; Проверка на ошибку
             02C5  74 07                        JZ      CLOSE_OK
             02C7  8D 16 016D R                 LEA     DX, BAD_CLOSE_MSG       ; Сообщение об ошибке
             02CB  E9 01E5 R                    JMP     ERROR_EXIT
             02CE                   CLOSE_OK:
             02CE  CD 20                        INT     20H             ; Возврат в ДОС
             02D0                   CODE    ENDS
                                          END
 
            Фиг. 5.6 Пример использования функциямй DOS (продолжение)
 
      Приведенная программа состоит из двух частей. В первой части
    создается файл из 26 записей длиной по 32 байта. Каждая запись
    соответствует одной букве алфавита: запись 1 - это "AAAA...A",
    запись 2 - "BBBB...B" и т.д. Данный файл формируется
    последовательно. Во второй части программы этот файл Mincho"'>    рассматривается как файл с произвольным доступом. В ответ на
    введенный пользователем с клавиатуры запрос программа считывает и
    выводит на дисплей одну из 26 записей. С помощью этого же ввода
    осущкствляется редактирование записи: 31 символ записи, начиная со
    второго, заменяется на значение, которое вводится с клавиатуры.
    Выполнение программы завершается при вводе с клавиатуры символа
    "$".
 
      В этом примере моделируется справочная база данных. На первом
    этапе программа осуществляет формирование этой базы данных. На
    втором этапе выполняется обработка произвольных запросов к базе
    данных и редактирование ее содержимого. Хотя любая реальная
    программа управления базой данных гораздо сложнее, чем приведенный
    здесь пример, однако он является хорошей иллюстрацией основных
    функций, относящихся к работе с файлами.
 
      Программа, приведенная на Фиг. 5.6, - это файл типа .COM. В
    следующем разделе мы обсудим различие между этим файлом и файлом
    типа .EXE. Использование в данном примере файла типа .COM позволяет
    для завершения работы программы воспользоваться прерыванием INT
    20H. В случае файла типа .COM начало программы в сегменте должно
    иметь смещение 100H. Первые 100H байт программного сегмента
    называются программным префиксом PSP и предназначены для хранения
    некоторых специальных данных, которые используются программной,
    написанной на языке ассемблера.
 
      Смещение блока FCB в сегменте равно 05CH, и использование в
    программе этого на первый взгляд произвольного адреса имеет
    определенные основания. Запись информации в данный блок FCB
    осуществляется командным процессором, входящим в состав DOS. После
    того, как пользователь вызвал программу, указав ее имя, DOS
    просматривает оставшуюся часть командной строки в поисках имен
    файлов. Первое встретившееся в команде имя помещается в блок FCB,
    смещение которого равно 05CH. Если в командной строке будет еще
    одно имя, то оно запишется в блок FCB со смещением 06CH. Так как в
    нашеи примере фигурирует только один файл, то используют только
    блок FCB со смещением 05CH. Запуск описываемой программы
    осуществляется с помощью следующей синтаксической конструкции:
 
      A> FIG5=6 TEST.FIL
 
      FIG5=6 - имя программы. В каталоге программа фигурирует под
    именем FIG5=6.COM. Файл TEST.FIL является файлом, который программа
    создает и затем модифицирует. Интерпретатор командных строк
    выбирает имя "TEST.FIL" и помещает его в соответствующее поле блока
    FCB со смещением 05CH. Рассматривая имя файла в качестве параметра
    командной строки, можно с помощью описываемой программы создавать и
    модифицировать любой файл. Если бы имя файла входило в ассемблерную
    программу, мы могли бы работать только с единственным файлом.
 
      Начиная со смещения 05CH, текст программы соответствует
    структуре блока FCB. Первая ячейка идентифицируется меткой блока
    FCB. Каждое из полей FCB имеет свою метку и длину, так что
    программа может обрабатывать их непосредственно. Например, чтобы
    задать длину записи, программа модифицирует переменную
    FCB_RECORD_SIZE.
 
      Начиная с адреса 080H помещается еще одно специальное поле
    программного префикса. Эта область памяти размером 128 байт
    отводится по умолчанию под область связи с диском DTA (Disk
    Transfer Area) и используется DOS в качестве буфера для всех
    файловых записей. Всякий раз, записывая или читая запись, DOS
    использует буфер области DTA. Во время инициализации DOS
    устанавливает смещение области DTA в программном сегменте равным
    080H. Программа может изменить это значение, используя функцию 1AH
    прерывания 21H. Это смещение должно быть изменено, еслм длина
    записи больше, чем 128 байт. В рассматриваемом примере область
    связи с диском сдвигается до смещения в сегменте, равного 90H. Это
    связано с тем, что блок FCB со смещением 05CH выходит за границу с
    адресом 80H. Если бы граница области DTA определялась соглашением,
    принятым по умолчанию, то при передаче файлов информация в
    последнем байте блока FCB была бы разрушена. В этом байте
    записывается номер записи при произвольном доступе к файлу. Так как
    в данной программе для чтения-записи данных используется
    произвольный доступ, упомянутое наложение информации необходимо
    исключить.
 
      Первая команда программы имеет смещение 100H и является
    переходом на фактическое начало программы. Такая структура
    программы может показаться неэффективной, однако ассемблирование
    происходит гораздо успешней, если все данные помещаются перед
    командами, которые на них ссылаются. Фактически в программе могут
    быть ошибки, если она содержит ссылки на данные вперед. Поэтому для
    большей надежности данные помещаются в начале программы.
 
      В первой части программы устанавливается область связи с
    диском. В данной программе эта буферная область имеет смещение 90H.
    Так как длина записи равняется только 32 байтам, то впереди
    программы имется достаточно места.
 
      Далее в программе используется прерывание 21H и функция DOS для
    поиска файла с именем, совпадающим с именем, записанным в блоке
    FCB. Обратите внимание, что пара регистров DC:DX указывает на блок
    FCB, как и должно быть при любых файловых операциях. Если система
    обнаружит файл с идентичным именем, программа завершит работу,
    выдав сообщение об ошибке и сохранив существующий уже файл. В
    данной программе обрабатываются только новые файлы. Существующие
    файлы здесь никак не используются, однако гарантируется, что их
    содержимое программой не сотрется. Конечно, в реальной практике
    програма была бы составлена так, чтобы охватывать случай как новых,
    так и уже существующих файлов.
 
      Создание файла обеспечивается участком программы, помещенным
    NO_FILE. Формировать блок FCB до этого данной программе не нужно,
    так как он был сформирован командным процессором. Если описываемая
    файловая операция не сможет быть выполнена, например, из-за
    отсутствия свободного места на диске или отсутствия места в
    каталоге диска, то программа завершит выполнение и выдаст
    соответствующее сообщение об ошибке.
      При любом обращении DOS к файлу программа должна, прежде всего,
    открыть файл. Процедура открытия файла устанавливает связь между
    операционной системой и пользовательской программой. В процессе
    этой операции DOS просматривает справочник диска, находит нужный
    файл (или не находит, что соответствует сбойной ситуации) и
    заполняет поле блока FCB, относящееся к длине файла. После того,
    как файл открыт, DOS не должна просматривать справочник диска
    всякий раз, когда происходит обращение к файлу. Система DOS
    сохраняет в блоке FCB информацию о файле до тех пор, пока она этот
    файл не "закроет". Термины "закрыть" и "открыть" файл еще раз
    указывают на связь с традиционным делопроизводством. Папку с файлом
    документов нужно открыть прежде, чем можно будет ознакомиться с
    содержащимся в ней бумагами, и закрыть до того, как ее уберут снова
    в бюро.
 
      В рассматриваемом примере открытие файла происходит при его
    создании. Если бы такой файл уже существовал, связь с ним была бы
    установлена с помощью функции открытия файла (AH=0FH). Если
    открытие файла произошло успешно, программма изменяет значения
    некоторых полей блока FCB. В частности, длина записи должна быть
    установлена равной 32 байт, так как по умолчанию DOS считает ее
    равной 128 байт.
 
      Часть программы с именем CHARACTER_LOOP передает в файл 26
    записей. Определяющий символ каждой записи передается в буфер
    области DTA оператором REP STOSB. Отдельные записи передаются на
    диск с помощью функции последовательной записи (AH=0AH). Программа
    также выполняет проверку на отсутствие ошибок.
 
      Начиная с метки KEYBOARD_LOOP программа переходит от
    формирования файла к запросу=коррекции записей в нем. В данном
    примере используется буферированный ввод с клавиатуры,
    поддерживаемый DOS. Это позволяет пользователю вводить строку из
    двух символов и, если необходимо, осуществлять редактирование.
    После ввода двух символов должна быть нажата клавиша окончания
    ввода. Программа выполняет проверку правильности ввода, и если
    последний не удовлетворяет требованиям, то он отвергается и
    выдается сообщение об ошибке.
 
      При вводе пользователем символа "$" программа заканчивает
    работу. В случае же ввода символов от "A" до "Z" программа
    осуществляет чтение соответствующей записи и выводит на дисплей ее
    содержимое. В оставшиеся 31 байт буфера программа записывает второй
    из введенных с клавиатуры символов. Модицифированная таким образом
    запись передается на диск в режиме произвольного доступа.
 
      В заключительной части программы осуществляется закрытие файла.
    Аналогично тому, как функция открытия файла устанавливала связь
    между DOS и пользовательской программой,
 
    ??????
 
      файла существенно для гарантии того, что DOS записала на диск все
    модифицированные записи. Во время нормального выполнения программы
    DOS может оставить несколько последних записей в буфере. Это
    ускоряет выполнение, так как DOS не должна обращаться к диску по
    поводу каждой записи. Функция закрытия файла осуществляет запись на
    диск содержимого буфера.
 
      Приведенный на Фиг. 5.6 пример программы иллюстрирует основные
    способы обращения к файлу с помощью DOS. Эта программа ничего
    полезного не выполняет, однако приближение ее к реальным задачам
    потребовало бы намного большего числа команд, которые мало что
    прояснили бы в отношении использования функций DOS. В данной
    программе важно обратить внимание на необходимость проверки ошибок
    после каждой операции, выполняемой DOS. В то время, как DOS с
    помощью прерывания 24H обрабатывает аппаратные ошибки,
    пользовательская программа должна разрешать такие ситуации, как
    совпадение имен файлов или отсутствие свободного места на дискете.
    В данном примере обработка ошибок проста и состоит из вывода
    соответствующего сообщения и завершения работ программы. Обработка
    ошибок в реальных программах значительно сложнее и более актуальна,
    так как в этом случае возможность потери важной информации должна
    быть исключена.
 
      И наконец, возможно, что проработав с данной программой, вы
    будете не очень удовлетворены ею как пользователь: в ней
    отсутствует запрос на ввод данных, сообщения об ошибках лаконичны и
    некоторые из выводимых сообщений частично накладываются на
    предыдущие, затирая их. Данная программа нуждается в доработке
    прежде, чем ею сможет воспользоваться кто-либо, не участвовавший в
    ее написании или тщательно в ней не разобравшийся.




Содержание раздела