Для выполнения операции ввода и вывода файлов в базовый 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