ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Вызов: АН = 14Н DS:DX - указатель на открытый FCB Возвращает: AL - 00H = прочитано успешно 01Н = конец файла 02Н = мало места в буфере диска 03Н = конец файла, неполная запись Комментарий: Функция 14Н читает запись из указанного файла. DX должен содержать смещение (сегментный адрес в DS) открытого FCB. Эта функция загружает запись, адресуемую полями Текущий блок (смещение 0СН) и Текущая запись (смещение 20Н) в буфер обмена с диском, после чего производит инкремент этих полей. Длина записи берется из поля Размер записи (смещение 0ЕН). Значение возвращаемого кода: Код Значение __________________________________________________________ 0 Прочитано успешно 1 Конец файла; нет данных в записи 2 Мало места в буфере обмена с диском для чтения одной записи; чтение отменяется 3 Конец файла; прочитана неполная запись и дополнена справа нулями до полной длины записи __________________________________________________________ Макроопределение: read-seq macro fcb mov dx,offset fcb mov ah,14H int 21H endm Пример: Следующая программа выводит на экран файл с именем textfile.asc на диске В. Ее функция аналогична функции команды MS-DOS TYPE. Если в буфере окажется неполная запись в конце файла, то она выводится до символа признака конца файла (ASCII 26 или CONTROL+Z). fcb db 2,"TEXTFILEASC" db 26 dup (?) buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН open fcb ; См. функцию 0FH read-line: read-seq fcb ; Наша функция cmp al,02H ; Буфер диска мал? je all-done ; Да cmp al,00H ; Конец файла? jg check-more ; Да display buffer ; См. функцию 09Н jmp read-line ; Получить след. запись check-more: cmp al,03H ; Неполная запись? jne all-done ; Нет, возврат - 52 - xor si,si ; Сброс индекса find-eof: cmp buffer[si],26 ; Это признак конца файла? je all-done ; Да, больше не отображать display-char buffer[si] ; См. функцию 02Н inc si ; Инкремент счетчика jmp find-eof ; Проверить след. символ all-done: close fcb ; См. функцию 10Н ЗАПИСАТЬ ПОСЛЕДОВАТЕЛЬНО ( ФУНКЦИЯ 15Н ) Вызов: АН = 15Н DS:DX - указатель на открытый FCB Возвращает: AL - 00H = записано успешно 01Н = диск заполнен 02Н = мал буфер диска Комментарий: Функция 15Н помещает запись в указанный файл. DX должен содержать смещение (сегментный адрес в DS) открытого FCB. Запись адресуется полями Текущий блок (смещение 0СН) и Текущая запись (смещение 20Н). После записи производится инкремент этих полей. Размер записи берется из поля Размер записи (смещение 0ЕН). Если размер записи меньше размера сектора, то данные из буфера обмена с диском записываются в буфер MS-DOS, откуда они записываются на диск при заполнении буфера до размера сектора, при закрытии файла или при вызове функции 0DH ( Сброс диска ). Значения возвращаемого кода: Код в AL Значение __________________________________________________________ 0 Записано успешно 1 Диск заполнен; запись отменяется 2 Мало места в буфере обмена с диском для одной записи; запись отменяется __________________________________________________________ Макроопределение: write-seq macro fcb mov dx,offset fcb mov ah,15H int 21H endm Пример: Следующая программа создает на диске В файл с именем dir.tmp, содержащий номера дисководов (0=А, 1=В и т.д.) и имена файлов из каждого каталогового входа. record-size equ 0EH ; Смещение поля Размер записи в FCB fcb1 db 2,"DIR TMP" db 26 dup (?) fcb2 db 2,"???????????" db 26 dup (?) buffer db 128 dup (?) ; - 53 - begin: set-dta buffer ; См. функцию 1АН search-first fcb2 ; См. функцию 11Н cmp al,0FFH ; Каталоговый вход найден? je all-done ; Нет, нет файлов на диске create fcb1 ; См. функцию 16Н mov fcb1[record-size],12 ; Установить размер ; записи равным 12 write-it: write-seq fcb1 ; Наша функция cmp al,0 ; Записано успешно? jne all-done ; Нет, возврат search-next fcb2 ; См. функцию 12Н cmp al,0FFH ; Каталоговый вход найден je all-done ; Нет, возврат jmp write-it ; Да, записать all-done: close fcb1 ; См. функцию 10Н СОЗДАТЬ ФАЙЛ ( ФУНКЦИЯ 16Н ) Вызов: АН = 16Н DS:DX - указатель на неоткрытый FCB Возвращает: AL - 00H = свободный вход найден FFH = нет свободных входов Комментарий: Функция 16Н создает файл. DX должен содержать смещение (сегментный адрес в DS) неоткрытого FCB. MS-DOS ищет в каталоге соответствующий вход, а если такового нет, то свободный вход. Если система находит соответствующий вход, она открывает файл и сбрасывает его длину в ноль ( другими словами, если вы пытаетесь создать уже существуюший файл, то он стирается и создается новый пустой файл). Если система не находит подходящий вход, но нашла свободный, она открывает файл и устанавливает его длину равной нулю. В обоих случаях AL возвращает 0, иначе - FFH. Устанавливая байт атрибута в расширенном FCB , вы можете присвоить файлу соответствующий атрибут ( см. Раздел 1.9.1, "Расширенный FCB"). Макроопределение: create macro fcb mov dx,offset fcb mov ah,16H int 21H endm Пример: Следующая программа создает на диске В файл с именем dir.tmp, содержащий номера дисководов (0=А, 1=В и т.д.) и имена файлов из каждого каталогового входа. record-size equ 0EH ; Смещение поля Размер записи в FCB fcb1 db 2,"DIR TMP" db 26 dup (?) fcb2 db 2,"???????????" - 54 - db 26 dup (?) buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН search-first fcb2 ; См. функцию 11Н cmp al,0FFH ; Каталоговый вход найден? je all-done ; Нет, нет файлов на диске create fcb1 ; Наша функция mov fcb1[record-size],12 ; Установить размер ; записи равным 12 write-it: write-seq fcb1 ; См. функцию 15Н cmp al,0 ; Записано успешно? jne all-done ; Нет, возврат search-next fcb2 ; См. функцию 12Н cmp al,0FFH ; Каталоговый вход найден je all-done ; Нет, возврат jmp write-it ; Да, записать all-done: close fcb1 ; См. функцию 10Н ПЕРЕИМЕНОВАТЬ ФАЙЛ ( ФУНКЦИЯ 17Н ) Вызов: АН = 17Н DS:DX - указатель на модифицированный FCB со следующим нестандартным форматом: Байт(ы) Содержание _________________________________ 00Н Номер дисковода 01Н-08Н Старое имя файла (при необходимости , допол- ненное справа пробелами) 09Н-0ВН Старое расширение ( при необходимости, допол- ненное справа пробелами) 0СН-10Н Обнулено 11Н-18Н Новое имя файла ( при необходимости допол- ненное справа пробелами) 19Н-1ВН Новое расширение ( при необходимости допол- ненное справа пробелами) 1СН-24Н Обнулено _________________________________ Возвращает: AL - 00H = каталоговый вход найден FFH = каталоговый вход не найден или файл с новым именем уже существует Комментарий: Функция 17Н переименовывает существующий файл. DX должен содержать смещение (сегментный адрес в DS) FCB модифицированного формата. MS-DOS ищет в каталоге вход, удовлетворяющий первому имени, которое может содержать символы заполнители. Если система находит соответствующий вход и не находит входа, удовлетворяющего второму имени, она заменяет имя файла - 55 - в каталоговом входе на второе имя файла из модифицированного FCB, при этом AL возвращает 0. Если второе имя содержит символы заполнители, то система не меняет соответствующие символы в имени файла в каталоговом входе. Эта функция не может быть использована для переименования скрытых, системных файлов и подкаталогов. Если система не находит соответствующего входа или находит вход для второго имени файла, то AL возвращает FFH. Макроопределение: rename macro fcb,newname mov dx,offset fcb mov ah,17H int 21H endm Пример: Следующая программа запрашивает старое и новое имя файла, а затем переименовывает файл. fcb db 37 dup (?) prompt1 db "Имя файла: $" prompt2 db "Новое имя: $" reply db 15 dup (?) crlf db 0DH,0AH,"$" ; begin: display prompt1 ; См. функцию 09Н get-string 15,reply ; См. функцию 0АН display crlf ; См. функцию 09Н parse reply[2],fcb ; См. функцию 29Н display prompt2 ; См. функцию 09Н get-string 15,reply ; См. функцию 0АН display crlf ; См. функцию 09Н parse reply[2],fc4b[16] ; См. функцию 29Н rename fcb ; Наша функция ПОЛУЧИТЬ ТЕКУЩИЙ ДИСК ( ФУНКЦИЯ 19Н ) Вызов: АН = 19Н Возвращает: AL - текущий дисковод (0=А, 1=В и т.д.) Комментарий: Функция возвращает код текущего дисковода. Макроопределение: current-disk macro mov ah,19H int 21H endm Пример: Следующая программа отображает на экране текущий дисковод в системе с двумя дисководами. message db "Текущий диск - $" - 56 - crlf db 0DH,0AH,"$" ; begin: display message ; См. функцию 09Н current-disk ; Наша функция cmp al,00H ; Это диск А? jne disk-b ; Нет, это диск В display-char "A" ; См. функцию 02Н jmp all-done disk-b: display-char "B" ; См. функцию 02Н all-done: display crlf ; См. функцию 09Н УСТАНОВИТЬ БУФЕР ОБМЕНА С ДИСКОМ ( ФУНКЦИЯ 1АН ) Вызов: АН = 1АН DS:DX - буфер обмена с диском Возвращает: -- Комментарий: DX должен содержать смещение (сегментный адрес в DS) Буфера обмена с диском. Буфер не должен заходить за границы сегмента. Если вы не установите свой буфер, то система по умолчанию создаст его со смещением 80Н в PSP (Префикс сегмента кодов). Узнать адрес текущего буфера можно с помощью функции 2FH. Макроопределение: set-dta macro buffer mov dx,offset buffer mov ah,1AH int 21H endm Пример: Следующая программа запрашивает букву, преобразует введенную букву в ее порядковый номер в алфавите, затем читает и выводит на экран соответствующую запись из файла с именем alphabet.dat, находящегося на диске В. Файл содержит 26 записей, каждая длиной 28 байт. record-size equ 0EH ; Смещение поля Размер записи в FCB relative-record equ 21H ; Смещение поля Относительная запись в FCB ; fcb db 2,"ALPHABETDAT" db 26 dup (?) buffer db 28 dup (?),"$" prompt db "Введите букву: $" crlf db 0DH,0AH,"$" ; begin: set-dta buffer ; Наша функция open fcb ; См. функцию 0FH mov fcb[record-size],28 ; Установить размер записи get-char: display prompt ; См. функцию 09Н read-kbd-and-echo ; См. функцию 01Н cmp al,0DH ; Это ВК - 57 - je all-done ; Да, возврат sub al,41H ; Преобразовать код ASCII в номер записи mov fcb[relative-record],al ; Установить ; относительную запись display crlf ; См. функцию 09Н read-ran fcb ; См. функцию 21Н display buffer ; См. функцию 09Н display crlf ; См. функцию 09Н jmp get-char ; Получить следующий символ all-done: close fcb ; См. функцию 10Н ПОЛУЧИТЬ ДАННЫЕ ТЕКУЩЕГО ДИСКА ( ФУНКЦИЯ 1ВН ) Вызов: АН = 1ВН Возвращает: количество AL - секторов на кластер СХ - байт на сектор DX - кластеров на диск DS:BX - указатель на байт FAT ID ( таблица размещения файла ) Комментарий: Функция возвращает данные о диске в текущем дисководе. BX возвращает смещение (сегментный адрес в DS) первого байта Таблицы размещения файла (FAT), который идентифицирует тип диска : Значение Тип диска __________________________________________________________ FF Двусторонний, 8 секторов на одной дорожке, 40 дорожек на одной стороне FE Односторонний, 8 секторов на одной дорожке, 40 дорожек на одной стороне FD Двусторонний, 9 секторов на одной дорожке, 40 дорожек на одной стороне FC Односторонний, 9 секторов на одной дорожке, 40 дорожек на одной стороне F9 Двусторонний, 15 секторов на одной дорожке, 40 дорожек на одной стороне F9 Двусторонний, 9 секторов на одной дорожке, 80 дорожек на одной стороне F8 Жесткий диск __________________________________________________________ Эта функция аналогична функции 36Н ( Получить свободное пространство диска ), за исключением того, что в BX она возвращает адрес байта FAT ID, а не количество имеющихся кластеров. Она также схожа с функцией 1СН ( Получить данные диска), но возвращает данные диска только из текущего дисковода. Подробнее, о том, как MS-DOS хранит данные на диске и о Таблице размещения файла, см. Главу 3, "MS-DOS Техническая информация". - 58 - __________________________________________________________ Предостережение Байт FAT ID больше не отвечает за идентификацию типа используемого диска. Подробнее, см. Главу 2, "MS-DOS Драйверы устройств". __________________________________________________________ Макроопределение: def-drive-data macro push ds mov ah,1BH int 21H mov al,byte ptr[bx] pop ds endm Пример: Следующая программа сообщает, является ли текущий диск флоппи-диском , или же текущим является жесткий диск. stdout equ 1 ; msg db "Текущий диск - " dskt db "Дискета." fixed db "Жесткий." crlf db 0DH,0AH ; begin: write-handle stdout,msg,17 ; См. функцию 40Н jc write-error ; Метка не показана def-drive-data ; Наша функция cmp byte ptr [bx],0F8H ; Проверить байт ; FAT ID jne disk ; Это жесткий диск? write-handle stdout,fixed,8 ; См. функцию 40Н jc write-error ; Метка не показана jmp short all-done ; Возврат disk: write-handle stdout,dskt,8 ; См. функцию 40Н all-done: write-handle stdout,crlf,2 ; См. функцию 40Н jc write-error ; Метка не показана ПОЛУЧИТЬ ДАННЫЕ ДИСКА ( ФУНКЦИЯ 1СН ) Вызов: АН = 1СН DL - дисковод (0=текущий, 1=А и т.д.) Возвращает: AL - FFH, если несуществующий дисковод, в противном случае количество секторов в кластере СХ - количество байт в секторе DX - количество кластеров на диске DS:BX - указатель на байт FAT ID Комментарий: Функция возвращает данные диска из указанного в DL дисковода. BX возвращает смещение (сегментный адрес в DS) первого байта - 59 - Таблицы размещения файла (FAT), который идентифицирует тип диска : Значение Тип диска __________________________________________________________ FF Двусторонний, 8 секторов на одной дорожке, 40 дорожек на одной стороне FE Односторонний, 8 секторов на одной дорожке, 40 дорожек на одной стороне FD Двусторонний, 9 секторов на одной дорожке, 40 дорожек на одной стороне FC Односторонний, 9 секторов на одной дорожке, 40 дорожек на одной стороне F9 Двусторонний, 15 секторов на одной дорожке, 40 дорожек на одной стороне F9 Двусторонний, 9 секторов на одной дорожке, 80 дорожек на одной стороне F8 Жесткий диск __________________________________________________________ Если в DL несуществующий номер, то AL возвращает FFH. Эта функция аналогична функции 36Н ( Получить свободное пространство диска ), за исключением того, что в BX она возвращает адрес байта FAT ID, а не количество имеющихся кластеров. Она также схожа с функцией 1ВН ( Получить данные текущего диска), но возвращает данные диска , указанного в DL . Подробнее, о том, как MS-DOS хранит данные на диске и о Таблице размещения файла, см. Главу 3, "MS-DOS Техническая информация". __________________________________________________________ Предостережение Байт FAT ID больше не отвечает за идентификацию типа используемого диска. Подробнее, см. Главу 2, "MS-DOS Драйверы устройств". __________________________________________________________ Макроопределение: drive-data macro drive push ds mov dl,drive mov ah,1CH int 21H mov al,byte ptr[bx] pop ds endm Пример: Следующая программа сообщает, является ли текущий диск флоппи-диском , или же текущим является жесткий диск. stdout equ 1 ; msg db "Текущий диск - " dskt db "Дискета." fixed db "Жесткий." crlf db 0DH,0AH ; begin: write-handle stdout,msg,17 ; См. функцию 40Н - 60 - jc write-error ; Метка не показана drive-data 2 ; Наша функция cmp byte ptr [bx],0F8H ; Проверить байт ; FAT ID jne disk ; Это жесткий диск? write-handle stdout,fixed,8 ; См. функцию 40Н jc write-error ; Метка не показана jmp short all-done ; Возврат disk: write-handle stdout,dskt,8 ; См. функцию 40Н all-done: write-handle stdout,crlf,2 ; См. функцию 40Н jc write-error ; Метка не показана ЧИТАТЬ ВЫБОРОЧНО ( ФУНКЦИЯ 21Н ) Вызов: АН = 21Н DS:DX - указатель на открытый FCB Возвращает: AL - 0 = прочитано успешно 1 = конец файла, пустая запись 2 = мало места в DTA 3 = конец файла, неполная запись Комментарий: Функция 21Н читает (в буфер обмена с диском) запись, адресуемую полем Относительная запись (смещение 21Н) в FCB. DX должен содержать смещение (сегментный адрес в DS) открытого FCB. Поля Текущий блок (смещение 0СН) и Текущая запись (смещение 20Н) устанавливаются в соответствии с полем Относительная запись. Длина записи берется из поля Размер записи (смещение 0ЕН) в FCB. AL возвращает код результата: Код Значение __________________________________________________________ 0 Прочитано успешно 1 Конец файла; нет данных в записи 2 Мало места в Буфере обмена с диском (DTA) для чтения одной записи; чтение отменяется 3 Конец файла; прочитана неполная запись и дополнена справа нулями до длины полной записи. __________________________________________________________ Макроопределение: read-ran macro fcb mov dx,offset fcb mov ah,21H int 21h endm Пример: Следующая программа запрашивает букву, преобразует введенную букву в ее порядковый номер в алфавите, затем читает и выводит на экран соответствующую запись из файла с именем alphabet.dat, находящегося на диске В. Файл содержит 26 записей, каждая длиной 28 байт. - 61 - record-size equ 0EH ; Смещение поля Размер записи в FCB relative-record equ 21H ; Смещение поля Относительная запись в FCB ; fcb db 2,"ALPHABETDAT" db 26 dup (?) buffer db 28 dup (?),"$" prompt db "Введите букву: $" crlf db 0DH,0AH,"$" ; begin: set-dta buffer ; См. функцию 1АН open fcb ; См. функцию 0FH mov fcb[record-size],28 ; Установить размер записи get-char: display prompt ; См. функцию 09Н read-kbd-and-echo ; См. функцию 01Н cmp al,0DH ; Это ВК je all-done ; Да, возврат sub al,41H ; Преобразовать код ASCII в номер записи mov fcb[relative-record],al ; Установить ; относительную запись display crlf ; См. функцию 09Н read-ran fcb ; Наша функция display buffer ; См. функцию 09Н display crlf ; См. функцию 09Н jmp get-char ; Получить следующий символ all-done: close fcb ; См. функцию 10Н ЗАПИСАТЬ ВЫБОРОЧНО ( ФУНКЦИЯ 22Н ) Вызов: АН = 22Н DS:DX - указатель на открытый FCB Возвращает: AL - 0 = записано успешно 1 = диск заполнен 2 = мало места в DTA Комментарий: Функция записывает из Блока обмена с диском (DTA) запись, адресуемую полем Относительная запись (смещение 21Н) в FCB. DX должен содержать смещение (сегментный адрес в DS) открытого FCB. Поля Текущий блок и Текущая запись (смещения соответственно 0СН и 20Н ) устанавливаются в зависимости от Относительной записи. После этого происходит запись с DTA. Размер записи берется из поля Размер записи в FCB. Если размер записи меньше размера сектора, то данные из DTA записываются в системный буфер, который записывается на диск при заполнении его до размера сектора, при закрытии файла или при вызове функции 0DH (Сброс диска). AL возвращает код результата операции: Код Значение __________________________________________________________ 0 Записано успешно 1 Диск заполнен 2 Мало места в Буфере обмена с диском для одной записи; запись отменяется __________________________________________________________ - 62 - Макроопределение: write-ran macro fcb mov dx,offset fcb mov ah,22H int 21H endm Пример: Следующая программа запрашивает букву, преобразует введенную букву в ее порядковый номер в алфавите, затем читает и выводит на экран соответствующую запись из файла с именем alphabet.dat, находящегося на диске В. После вывода на экран этой записи, программа запрашивает ввод измененной записи. Если вы введете измененную запись, то она будет записана в файл. Если вы просто нажмете ВВОД, то запись заменена не будет. Файл содержит 26 записей, каждая длиной 28 байт. record-size equ 0EH ; Смещение поля Размер записи в FCB relative-record equ 21H ; Смещение поля Относительная запись в FCB ; fcb db 2,"ALPHABETDAT" db 26 dup (?) buffer db 28 dup (?),"$" prompt1 db "Введите букву: $" prompt2 db "Новая запись (ВВОД если нет изменений): $" crlf db 0DH,0AH,"$" reply db 28 dup (32) blanks db 26 dup (32) ; begin: set-dta buffer ; См. функцию 1АН open fcb ; См. функцию 0FH mov fcb[record-size],28 ; Установить размер записи get-char: display prompt1 ; См. функцию 09Н read-kbd-and-echo ; См. функцию 01Н cmp al,0DH ; Это ВК je all-done ; Да, возврат sub al,41H ; Преобразовать код ASCII в номер записи mov fcb[relative-record],al ; Установить ; относительную запись display crlf ; См. функцию 09Н read-ran fcb ; Наша функция display buffer ; См. функцию 09Н display crlf ; См. функцию 09Н display prompt2 ; См. функцию 09Н get-string 27,reply ; См. функцию 0АН display crlf ; См. функцию 09Н cmp reply[1],0 ; Что-нибудь введено,кроме ВК? je get-char ; Нет, другой символ xor bx,bx ; Сброс mov bl,reply[1] ; Длину reply в качестве счетчика mov-string blanks,buffer,26 ; См. конец главы mov-string replay[2],buffer,bx ; См. конец главы write-ran fcb ; Наша функция jmp get-char ; Получить следующий символ all-done: close fcb ; См. функцию 10Н - 63 - ПОЛУЧИТЬ РАЗМЕР ФАЙЛА ( ФУНКЦИЯ 23Н ) Вызов: АН = 23Н DS:DX - указатель на неоткрытый FCB Возвращает: AL - 00H = каталоговый вход найден FFH = каталоговый вход не найден Комментарий: Функция 23Н возвращает размер указанного файла. DX должен содержать смещение (сегментный адрес в DS) неоткрытого FCB. Если каталоговый вход найден, то MS-DOS делит значение поля Размер файла (смещение 10Н) каталогового входа на значение поля Размер записи (смещение 0ЕН) FCB. Результат помещается в поле Относительная запись (смещение 21Н) FCB, а AL возвращает 0. Вам неоходимо выставить поле Размер записи в блоке управления файлом (FCB) перед вызовом этой функции. Если размер записи не является делителем размера файла, то результат округляется в сторону увеличения. Если вход не найден, AL возвращает FFH. Макроопределение: file-size macro fcb mov dx,offset fcb mov ah,23H int 21H endm Пример: Следующая программа запрашивает имя файла, открывает его для заполнения поля Размер записи в FCB, вызывает функцию 23Н и выводит на экран длину записи и количество записей. fcb db 37 dup (?) prompt db "Имя файла: $" msg1 db "Длина записи: ",0DH,0AH,"$" msg2 db "Записей: ",0DH,0AH,"$" crlf db 0DH,0AH,"$" reply db 17 dup (?) ; begin: display prompt ; См. функцию 09Н get-string 17,reply ; См. функцию 0АН cmp reply[1],0 ; Это ВК? jne get-length ; Нет, продолжать jmp all-done ; Да, возврат get-length: display crlf ; См. фунуцию 09Н parse reply[2],fcb ; См. функцию 29Н open fcb ; См. функцию 0FH file-size fcb ; Наша функция mov ax,word ptr fcb[33] ; Получить длину записи convert ax,10,msg2[9] ; См. конец главы mov ax,word ptr fcb[14] ; Получить количество записей convert ax,10,msg1[15] ; См. конец главы display msg1 ; См. функцию 09Н display msg2 ; См. функцию 09Н all-done: close fcb ; См. функцию 10Н - 64 - УСТАНОВИТЬ ОТНОСИТЕЛЬНУЮ ЗАПИСЬ ( ФУНКЦИЯ 24Н ) Вызов: АН = 24Н DS:DX - указатель на открытый FCB Возвращает: -- AL = 00H - поле относительной записи в FCB изменено. Комментарий: Функция устанавливает поле Относительная запись (смещение 21Н) в соответствие с полями Текущий блок (смещение 0СН) и Текущая запись (смещение 20Н). DX должен содержать смещение (сегментный адрес в DS) открытого FCB. Пользуйтесь этой функцией перед выборочными чтением и записью ( функции 21Н, 22Н, 27Н или 28Н). Макроопределение: set-relative-record macro fcb mov dx,offset fcb mov ah,24H int 21H endm Пример: Следующая программа копирует файл, используя функции 27Н и 28Н. Копирование значительно ускорено путем установки длины записи равной длине файла, счетчика записей - 1 и использованием буфера в 32К. Указатель файла позиционируется установкой поля Текущая запись в 1 и использованием функции 24Н (Установить относительную запись) . Таким образом, указатель файла адресует ту же запись в файле, что и комбинация полей Текущий блок и Текущая запись. current-record equ 20H ; Смещение поля Текущая запись в FCB file-size equ 10H ; Смещение поля Размер файла в FCB ; fcb db 37 dup (?) filename db 17 dup (?) prompt1 db "Копировать файл: $" ; Об'яснение симво- prompt2 db "Имя копии: $" ; ла $ дается в описании ; функции 09Н crlf db 0DH,0AH,"$" file-length dw ? buffer db 32767 dup (?) ; begin: set-dta buffer ; См. функцию 1АН display prompt1 ; См. функцию 09Н get-string 15,filename ; См. функцию 0АН display crlf ; См. функцию 09Н parse filename[2],fcb ; См. функцию 29Н open fcb ; См. функцию 0FH mov fcb[current-record],0 ; Установка поля ; Текущая запись set-relative-record fcb ; Наша функция mov ax,word ptr fcb[file-size] ; Получить - 65 - ; размер файла mov file-length,ax ; Сохранить его ; для выборочной ; записи ran-block-read fcb,1,ax ; См. функцию 27Н display prompt2 ; См. функцию 09Н get-string 15,filename ; См. функцию 0АН display crlf ; См. функцию 09Н parse filename[2],fcb ; См. функцию 29Н create fcb ; См. функцию 16Н mov fcb[current-record],0 ; Установка поля ; Текущая запись set-relative-record fcb ; Наша функция mov ax,file-length ; Восстановить размер ran-block-write fcb,1,ax ; См. функцию 28Н close fcb ; См. фунуцию 10Н - 66 - УСТАНОВИТЬ ВЕКТОР ПРЕРЫВАНИЯ ( ФУНКЦИЯ 25Н ) Вызов: АН = 25Н AL - номер прерывания DS:DX - указатель на процедуру обслуживания прерывания Возвращает: -- Комментарий: Функция 25Н устанавливает адрес прерывания в таблице векторов для указанного прерывания. AL должен содержать номер прерывания. DX - смещение (сегментный адрес в DS) процедуры обслуживания прерывания. Для избежания проблем совместимости , программы никогда не должны напрямую устанавливать вектор или использовать Прерывание 25Н для прямого чтения из памяти. Для получения вектора используйте функцию 35Н ( Получить вектор прерывания), а для установки - Функцию 25Н, если необязательно, чтобы ваши программы были совместимы с версиями системы до 2.0. Макроопределение: set-vector macro interrupt,handler-start mov al,interrupt mov dx,offset handler-start mov ah,25H int 21H endm Пример: Так как прерывания обычно имеют специфику конкретной машины, пример не показан. СОЗДАТЬ НОВЫЙ PSP ( ФУНКЦИЯ 26Н ) Вызов: АН = 26Н DX - сегментный адрес нового PSP Возвращает: -- Комментарий: Эта функция была заменена. Используйте функцию 4ВН (Загрузить и выполнить программу или наложить) для запуска дочерних программ, если нет необходимости в совместимости ваших программ с версиями системы до 2.0. Функция создает новый Префикс сегмента кодов (PSP). Его сегментный адрес должен быть загружен в DX. Макроопределение: create-psp macro seg-addr mov dx,seg-addr mov ah,26H int 21H endm - 67 - Пример: Так как эта функция была заменена на функции 4В00Н и 4В03Н, пример не показан. ЧИТАТЬ БЛОК ВЫБОРОЧНО ( ФУНКЦИЯ 27Н ) Вызов: АН = 27Н СХ - количество блоков для чтения DS:DX - указатель на открытый FCB Возвращает : AL - 0 = прочитано успешно 1 = конец файла, пустая запись 2 = мало места в DTA 3 = конец файла, неполная запись СХ - количество прочитанных блоков Комментарий: Функция 27Н читает одну или несколько записей из указанного файла в Буфер обмена с диском (DTA). DX должен содержать смещение (сегментный адрес в DS) открытого FCB. СХ должен содержать количество записей, которое нужно прочитать. Чтение начинается с записи, адресуемой полем Относительная запись (смещение 21Н). Это поле необходимо выставить перед вызовом этой функции. MS-DOS подсчитывает количество байт для чтения путем умножения значения СХ на значение поля Размер записи (смещение 0ЕН) FCB. СХ возвращает количество прочитанных записей. Поля Текущий блок (смещение 0СН), Текущая запись (смещение 20Н) и Относительная запись теперь адресуют следующую запись. При вызове этой функции с СХ, равным 0, не будет прочитано ни одной записи. AL возвращает код результата операции: Код Значение __________________________________________________________ 0 Прочитано успешно 1 Конец файла; нет данных в записи 2 Мало места в Буфере обмена с диском для чтения одной записи; чтение отменяется 3 Конец файла; прочитана неполная запись и допол- нена справа нулями до полной длины. __________________________________________________________ Макроопределение: ran-block-read macro fcb,count,rec-size mov dx,offset fcb mov cx,count mov word ptr fcb[14],rec-size mov ah,27H int 21H endm - 68 - Пример: Следующая программа копирует файл, используя функции 27Н и 28Н. Копирование значительно ускорено путем установки длины записи равной длине файла, счетчика записей - 1 и использованием буфера в 32К. Файл читается как одна запись ( сравните с примером функции 28Н, где длина записи = 1, а счетчик записей = размеру файла). current-record equ 20H ; Смещение поля Текущая запись в FCB file-size equ 10H ; Смещение поля Размер файла в FCB ; fcb db 37 dup (?) filename db 17 dup (?) prompt1 db "Копировать файл: $" ; Об'яснение симво- prompt2 db "Имя копии: $" ; ла $ дается в описании ; функции 09Н crlf db 0DH,0AH,"$" file-length dw ? buffer db 32767 dup (?) ; begin: set-dta buffer ; См. функцию 1АН display prompt1 ; См. функцию 09Н get-string 15,filename ; См. функцию 0АН display crlf ; См. функцию 09Н parse filename[2],fcb ; См. функцию 29Н open fcb ; См. функцию 0FH mov fcb[current-record],0 ; Установка поля ; Текущая запись set-relative-record fcb ; См. функцию 24Н mov ax,word ptr fcb[file-size] ; Получить ; размер файла mov file-length,ax ; Сохранить его ; для выборочной ; записи ran-block-read fcb,1,ax ; Наша функция display prompt2 ; См. функцию 09Н get-string 15,filename ; См. функцию 0АН display crlf ; См. функцию 09Н parse filename[2],fcb ; См. функцию 29Н create fcb ; См. функцию 16Н mov fcb[current-record],0 ; Установка поля ; Текущая запись set-relative-record fcb ; См. функцию 24Н mov ax,file-length ; Восстановить размер ran-block-write fcb,1,ax ; См. функцию 28Н close fcb ; См. фунуцию 10Н - 69 - ЗАПИСАТЬ БЛОК ВЫБОРОЧНО ( ФУНКЦИЯ 28Н ) Вызов: АН = 28Н СХ - количество блоков для чтения ( 0 - установка поля Размер файла) DS:DX - указатель на открытый FCB Возвращает: AL - 0 = записано успешно 1 = диск заполнен 2 = конец сегмента СХ - количество прочитанных блоков Комментарий: Функция записывает одну или несколько записей в указанный файл из Буфера обмена с диском (DTA). DX должен содержать смещение (сегментный адрес в DS) открытого FCB. В СХ должно быть либо количество записей для чтения, либо 0. Если СХ не ноль, то указанное количество записей записывается в файл, начиная с записи, адресуемой полем Относительная запись (смещение 21Н) FCB. Если СХ - 0, то ничего не записывается , а MS-DOS устанавливает поле размер файла (смещение 10Н) в каталоговом входе равным значению поля Относительная запись (смещение 21Н) в FCB. В соответствии с новым размером файла , дисковые кластеры либо выделяются, либо освобождаются. MS-DOS подсчитывает количество байт для записи путем умножения содержимого СХ на значение поля Размер записи (смещение 0ЕН) FCB. СХ возвращает количество записанных блоков. Поля Текущий блок (смещение 0СН), Текущая запись (смещение 20Н) и Относительная запись (смещение 21Н) адресуют теперь следующую запись. AL возвращает код результата операции: Код Значение __________________________________________________________ 0 Записано успешно 1 Диск заполнен. Ничего не записано 2 Мало места в Буфере обмена с диском для одной записи. Запись отменяется __________________________________________________________ Макроопределение: ran-block-write macro fcb,count,rec-size mov dx,offset fcb mov cx,count mov word ptr fcb[14],rec-size mov ah,28H int 21H endm Пример: Следующая программа копирует файл, используя функции 27Н и 28Н. Копирование значительно ускорено путем установки длины записи равной 1 , а счетчика записей - размеру файла и использованием буфера в 32К. Чтение и запись осуществляются за один доступ к диску. ( Сравните с примером функции 27Н, где длина записи = размеру размеру файла, счетчик записей = 1). - 70 - current-record equ 20H ; Смещение поля Текущая запись в FCB file-size equ 10H ; Смещение поля Размер файла в FCB ; fcb db 37 dup (?) filename db 17 dup (?) prompt1 db "Копировать файл: $" ; Об'яснение симво- prompt2 db "Имя копии: $" ; ла $ дается в описании ; функции 09Н crlf db 0DH,0AH,"$" buffer db 32767 dup (?) num-recs dw ? ; begin: set-dta buffer ; См. функцию 1АН display prompt1 ; См. функцию 09Н get-string 15,filename ; См. функцию 0АН display crlf ; См. функцию 09Н parse filename[2],fcb ; См. функцию 29Н open fcb ; См. функцию 0FH mov fcb[current-record],0 ; Установка поля ; Текущая запись set-relative-record fcb ; См. функцию 24Н mov ax,word ptr fcb[file-size] ; Получить ; размер файла mov num-recs,ax ; Сохранить его ; для выборочной ; записи ran-block-read fcb,num-recs,1 ; См. функцию 27Н display prompt2 ; См. функцию 09Н get-string 15,filename ; См. функцию 0АН display crlf ; См. функцию 09Н parse filename[2],fcb ; См. функцию 29Н create fcb ; См. функцию 16Н mov fcb[current-record],0 ; Установка поля ; Текущая запись set-relative-record fcb ; См. функцию 24Н ran-block-write fcb,num-recs,1 ; Наша функция close fcb ; См. фунуцию 10Н РАЗОБРАТЬ ИМЯ ФАЙЛА ( ФУНКЦИЯ 29Н ) Вызов: АН = 29Н AL - управляет разбором DS:SI - указатель на разбираемую строку ES:DI - указатель на буфер для неоткрытого FCB Возвращает: AL - 00H = нет символов заполнителей 01Н = есть символы заполнители FFH = несуществующее имя дисковода DS:SI - указатель на первый байт после разобранной строки ES:DI - указатель на неоткрытый FCB - 71 - Комментарий: Функция 29Н производит анализ строки на имя файла по принципу - дисковод:имя_файла.расширение. SI должен содержать смещение (сегментный адрес в DS) разбираемой строки. DI должен содержать смещение (сегментный адрес в ES) достаточно большого участка памяти для неоткрытого FCB. Если строка содержит разрешенное имя файла, то система создает соответствующий неоткрытый FCB по ES:DI. AL контролирует разбор. Биты 4-7 должны быть нулями, а биты 0-3 имеют следующий смысл: Таблица 1.20 __________________________________________________________ Бит Действие __________________________________________________________ 0 0 Останавливает разбор, если встречает разделитель 1 Игнорирует лидирующие разделители 1 0 Если строка не содержит номер дисковода, то в FCB он выставляется в 0 (текущий) 1 Оставляет номер дисковода в FCB неизменным, если строка не содержит номер дисковода 2 0 Вставляет в имя файла в FCB 8 пробелов, если строка не содержит имени файла 1 Оставляет имя файла неизменным в FCB, если строка не содержит имени файла 3 0 Вставляет 3 пробела в расширение имени в FCB, если строка не содержит расширения 1 Оставляет расширение имени в FCB неизменным, если строка не содержит расширения __________________________________________________________ Если строка содержит имя файла или его расширение с с символом (*), то все остальные символы имени или расширения заменяются на символ (?). Разделители имени файла: : ; . , = + / " [ ] \ < > | таб Если строка содержит разрешенное имя файла, то: - AL возвращает 0, если в имени или расширении есть символы заполнители, и 1, если их нет в спецификации. - DS:SI адресуют символ, следующий за разобранной строкой. - ES:DI адресуют первый байт неоткрытого FCB. Если имя дисковода не существует, то AL возвращает FFH. Если строка не содержит разрешенное имя файла, то ES:DI+1 адресуют пробел. Макроопределение: parse macro string,fcb mov si,offset string mov di,offset fcb push es push ds pop es mov al,0FH ; Биты 0-3 в 1 mov ah,29H - 72 - int 21H pop es endm Пример: Следующая программа проверяет существование файла, имя которого вы вводите на запрос. fcb db 37 dup (?) prompt db "Имя файла: $" reply db 17 dup (?) yes db "Файл существует",0DH,0AH,"$" no db "Файл не существует",0DH,0AH,"$" crlf db 0DH,0AH,"$" ; begin: display prompt ; См. функцию 09Н get-string 15,reply ; См. функцию 0АН parse reply[2],fcb ; Наша функция display crlf ; См. функцию 09Н search-first fcb ; См. функцию 11Н cmp al,0FFH ; Каталоговый вход найден? je not-there ; Нет display yes ; См. функцию 09Н jmp return ; Метка не показана not-there: display no ; См. функцию 09Н ПОЛУЧИТЬ ДАТУ ( ФУНКЦИЯ 2АН ) Вызов: АН = 2АН Возвращает: СХ - год ( 1980-2099 ) DH - месяц ( 1-12 ) DL - число ( 1-31 ) AL - день недели ( 0=Вс., 6=Сб. и т.д. ) Комментарий: Функция 2АН возвращает текущую дату операционной системы. Макроопределение: get-date macro mov ah,2AH int 21H endm Пример: Следующая программа получает дату, производит инкремент дня, а если нужно, то и месяца, после чего устанавливает новую дату. month db 31,28,31,30,31,30,31,31,30,31,30,31 ; begin: get-date ; Наша функция inc dl ; Инкремент дня xor bx,bx ; BL в качестве индекса mov bl,dh ; Месяца в индекс dec bx ; Отсчет в таблице - 73 - месяцев с нуля cmp dl,month[bx] ; Месяц прошел? jle month-ok ; Нет, установить дату mov dl,1 ; Да, сброс дней в 1 inc dh ; и инкремент месяцев cmp dh,12 ; Год закончился? jle month-ok ; Нет, установить дату mov dh,1 ; Да, сброс месяцев в 1 inc cx ; и инкремент года month-ok: set-date cx,dh,dl ; См. функцию 2АН УСТАНОВИТЬ ДАТУ ( ФУНКЦИЯ 2ВН ) Вызов: АН = 2ВН СХ - год ( 1980-2099 ) DH - месяц ( 1-12 ) DL - день ( 1-31 ) Возвращает: AL - 00H = разрешенная дата FFH = несуществующая дата Комментарий: Функция устанавливает дату операционной системы. Регистры DX и CX должны содержать разрешенную дату в двоичном коде. Макроопределение: set-date macro year,month,day mov cx,year mov dh,month mov dl,day mov ah,2BH int 21H endm Пример: Следующая программа получает дату, производит инкремент дня, а если нужно, то и месяца, после чего устанавливает новую дату. month db 31,28,31,30,31,30,31,31,30,31,30,31 ; begin: get-date ; См. функцию 2АН inc dl ; Инкремент дня xor bx,bx ; BL в качестве индекса mov bl,dh ; Месяца в индекс dec bx ; Отсчет в таблице месяцев с нуля cmp dl,month[bx] ; Месяц прошел? jle month-ok ; Нет, установить дату mov dl,1 ; Да, сброс дней в 1 inc dh ; и инкремент месяцев cmp dh,12 ; Год закончился? jle month-ok ; Нет, установить дату mov dh,1 ; Да, сброс месяцев в 1 inc cx ; и инкремент года month-ok: set-date cx,dh,dl ; Наша функция - 74 - ПОЛУЧИТЬ ВРЕМЯ ( ФУНКЦИЯ 2СН ) Вызов: АН = 2СН Возвращает: СН - часы ( 0-23 ) CL - минуты ( 0-59 ) DH - секунды ( 0-59 ) DL - сотые доли секунды ( 0-99 ) Комментарий: Функция 2СН возвращает время операционной системы в регистрах CX и DX в двоичном коде. В зависимости от аппаратной реализации отсчета времени, некоторые поля регистров не используются . Например, многие чипы с часами не выделяют долей секунды. В таких случаях значение DL, скорее всего, будет всегда равно 0. Макроопределение: get-time macro mov ah,2ch int 21h endm Пример: Следующая программа непрерывно отображает время до нажатия любой клавиши: time db "00:00:00.00",0DH,0AH,"$" . . begin: get-time ; Наша функция byte-to-dec ch,time ; См. конец главы byte-to-dec cl,time[3] ; См. конец главы byte-to dec dh,time[6] ; См. конец главы byte-to dec dl,time[9] ; См. конец главы display time ; См. функцию 09Н check-kbd-status ; См. функцию 0ВН cmp al,0FFH ; Есть символы? je return ; Да, возврат jmp begin ; Нет, продолжать ; индикацию времени УСТАНОВИТЬ ВРЕМЯ ( ФУНКЦИЯ 2DH ) Вызов: АН = 2DH СН - часы ( 0-23 ) CL - минуты ( 0-59 ) DH - секунды ( 0-59 ) DL - сотые доли секунды ( 0-99 ) Возвращает: AL - 00H - разрешенное время FFH - несуществующее время - 75 - Комментарий: Функция 2СН возвращает время операционной системы в регистрах CX и DX в двоичном коде. В зависимости от аппаратной реализации отсчета времени, некоторые поля регистров не используются . Например, многие чипы с часами не выделяют долей секунды. В таких случаях значение DL не будет использоваться. Макроопределение: set-time macro hour,minutes,seconds,hundredths mov ch,hour mov cl,minutes mov dh,seconds mov dl,hundredths mov ah,2DH int 21H endm Пример: Следующая программа сбрасывает системные часы в ноль и отображает время непрерывно. При вводе символа экран замирает. При вводе следующего символа, часы сбрасываются в ноль, а индикация времени продолжается. time db "00:00:00.00",0DH,0AH,"$" . . begin: set-time 0,0,0,0 ; Наша функция read-clock: get-time ; См. функцию 2СН byte-to-dec ch,time ; См. конец главы byte-to-dec cl,time[3] ; См. конец главы byte-to dec dh,time[6] ; См. конец главы byte-to dec dl,time[9] ; См. конец главы display time ; См. функцию 09Н dir-console-io 0FFH ; См. функцию 06Н cmp al,00H ; Есть символы? jne stop ; Да, стоп таймер jmp read-clock ; Нет, продолжать ; индикацию времени stop: read-kbd ; См. функцию 08Н jmp begin ; Продолжить УТАНОВИТЬ/СБРОСИТЬ ФЛАГ ПРОВЕРКИ ( ФУНКЦИЯ 2ЕН ) Вызов: АН = 2ЕН AL - 0 = не проверять 1 = проверять Возвращает: -- Комментарий: Функция 2ЕН сообщает системе, проверять или нет каждую запись на диск. Если AL = 1, то проверять ; если AL = 0 ,то не проверять. В свою очередь, система проверяет этот флаг перед каждой операцией записи на диск. В нормальном положении флаг сброшен. Вы можете его - 76 - установить , если записываются очень важные данные. Установка флага снижает скорость записи. Вы можете проверить установку флага с помощью функции 54Н ( Получить состояние флага проверки). Макроопределение: verify macro switch mov al,switch mov ah,2EH int 21H endm Пример: Следующая программа копирует содержимое одностороннего диска А на диск В, проверяя каждую запись. Программа использует буфер в 32К. on equ 1 off equ 0 ; prompt db "Источник в А, адресат в В",0DH,0AH db "Нажмите любую клавишу. $" first dw 0 buffer db 60 dup (512 dup (?)) ; 60 секторов ; begin: display prompt ; См. функцию 09Н read-kbd ; См. функцию 08Н verify on ; Наша функция mov cx,6 ; Копировать 60 секторов ; 6 раз copy: push cx ; Сохранить счетчик abs-disk-read 0,buffer,60,first ; См. преры- ; вание 25Н abs-disk-write 1,buffer,64,first ; См. преры- ; вание 26Н add first,60 ; Следующие 60 секторов pop cx ; Восстановить счетчик loop copy ; Еще раз verify off ; Наша функция endm mov ah,59H int 21H endm © KOAP Open Portal 2000 |