8.3. Чтение и запись файла с помощью FCB

Для выполнения операции ввода и вывода файлов в базовый DOS необходимо в сегменте данных определить блок управления файлов (FCB). Блок FCB содержит описание файла и его записей в следующем ниже формате. Программист должен инициализировать байты 0-15 и 32-36. Остальные байты установит DOS.

Байты

Назначение

0

Дисковод, 01 для A, 02 для B и т.д., 0-текущий дисковод

1-8

Имя файла, дополненное справа пробелами

9-11

Расширение файла

12-13

Номер текущего блока. Блок содержит 128 записей. Номер текущей записи находится в байте 32. Первый блок имеет номер 0. После открытия файла равен 0

14-15

Логический размер записи. При открытии файла устанавливается в 0. Можно установить любое другое число

16-19

Размер файла. Это поле изменить нельзя

20-21

Дата создания или изменения

22-31

Резерв

32

Текущий номер записи в текущем блоке (см. байты 12-13)

33-36

Относительный номер записи

Для создания нового файла на диске используются следующие функции прерывания 21h:

16h — создание файла

1Ah — установка адреса области передачи данных DTA

15h — запись из области DTA в файл

10h — закрытие файла

В сегменте данных надо определить блок FCB и буфер DTA для данных, которые будут записываться на диск:

fcb     db  1          ;дисковод A

        db  ‘filename’

        db  ‘ext’

blkptr  dw  0          ;номер текущего блока

recsize dw  ?          ;размер записи

        dw  8 dup(?)   ;байты 16-31

recptr  db  0          ;номер текущей записи

        dw  2 dup(?)   ;байты 33-36

buffer  db  512 dup(?)

Для создания файла filename.ext выполнить команды

      mov   ah,16h

      lea   dx,fcb

      int   21h

Размер записи устанавливается при открытии по умолчанию 128 байт. Перед записью данных его можно изменить.

Буфер, из которого будут записываться данные на диск, устанавливается командами

      mov   ah,1Ah

      lea   dx,buffer

      int   21h

С помощью функции 15h осуществляется запись содержимого буфера DTA на диск:

      mov   ah,15h

      lea   dx,fcb

      int   21h

Размер файла в блоке FCB и текущие номера записи и блока изменяет DOS. В конце работы следует закрыть файл:

      mov   ah,10h

      lea   dx,fcb

      int   21h

Рассмотрим теперь операцию чтения файла по FCB. Для чтения файла необходимо вызвать следующие функции прерывания 21h:

0Fh — открытие файла

1Ah — формирование адреса буфера

14h — чтение данных из файла в буфер

Открытие файла осуществляется командами

      mov   ah,0Fh

      lea   dx,fcb

      int   21h

Установка буфера DTA рассматривалась выше. После установки буфера DTA осуществляется чтение:

      mov   ah,14h

      lea   dx,fcb

      int   21h

Так как при чтении файла записи в каталоге не изменяются, то нет необходимости закрывать файл после завершения чтения.

Напишем программу, читающую собственный текст и выводящую его на экран:

< 1 > title     fcb.exe

< 2 > mycode     segment

< 3 > assume    cs:mycode, ds:mydata

< 4 > ;—————————————————

< 5 > extrn     display:near, ascii:near, hex:near

< 6 > extrn     kbin:near, crlf:near, hexw:near

< 7 > bufsize    equ   512

< 8 > nchar      equ   64

< 9 > ;——открытие файла———————-

< 10 > open proc

< 11 > lea       dx,fcb

< 12 > mov       ah,0fh

< 13 > int       21h

< 14 > mov       ax,bufsize

< 15 > mov       recsize,ax

< 16 > ret

< 17 > open     endp

< 18 > ;——установка адреса области DTA———

< 19 > setbuf   proc

lea   dx,buffer

< 1 >

< 2 > mov       ah,1Ah

< 3 > int       21h

< 4 > ret

< 5 > setbuf   endp

< 6 > ;——чтение в буфер———————-

< 7 > read     proc

< 8 > lea       dx,fcb

< 9 > mov       ah,14h

< 10 > int       21h

< 11 > ret

< 12 > read     endp

< 13 > ;——вывод cx строк из буфера bx———

< 14 > show     proc

< 15 > mov       dx,bx

< 16 > call      hexw

< 17 > mov       dl,’ ‘

< 18 > call      display

< 19 > mov       di, nchar  ;64 символа

< 20 > next:

< 21 > mov       dl,[bx]

< 22 > call      ascii

< 23 > inc       bx

< 24 > dec       di

< 25 > jnz       next

< 26 > call      crlf

< 27 > loop      show       ;вывод cx строк

< 28 > ret

< 29 > show     endp

< 30 > ;——главная программа———————

< 31 > main     proc  far

< 32 > push      es         ;адрес

< 33 > mov       ax,0       ;возврата DOS

< 34 > push      ax

< 35 > mov       ax,mydata  ;инициализация

< 36 > mov       ds,ax      ;регистра ds

< 37 > call      open       ;открыть файл

< 38 > mov       bx,offset fcb

< 39 > mov       cx,1

< 40 > call      show       ;показать 32 байта fcb

< 41 > call      crlf

< 42 > call      setbuf

< 43 > call      read

< 44 > mov       bx,offset buffer

< 45 > mov       cx,20

< 46 > call      show       ;вывести 20 строк по 32 байта

< 47 > ret

< 48 > main     endp

< 49 > mycode   ends

< 50 > ;——данные——————————-

< 51 > mydata   segment

< 52 > fcb  db    0, ‘fcb     ‘

< 53 > db ‘asm’

< 54 > blkptr   dw    0

< 55 > recsize    dw    (?)

< 56 > db       24 dup(?)   ;дополнение до 40 байт

< 57 > buffer   db    bufsize dup(?)

< 58 > mydata   ends

< 59 > end       main