ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Вызов: AL - номер дисковода DS:BX - адрес буфера диска или адрес блока параметров ( при CX = -1 ) CX - количество секторов или -1 DX - начальный относительный сектор Возвращает: AL - код ошибки, если CF = 1 FLAGS CF = 1 при успешном завершении = 0 сбой АХ - 0207, если была сделана попытка получить доступ к разделу, большему чем 32 мегабайта из MS-DOS до 3.3 включительно. Комментарий: Регистры должны содержать следующее: Регистр Содержимое __________________________________________________________ AL Номер дисковода (0=А, 1=В и т.д.) DS:BX Адрес буфера обмена с диском или адрес блока параметров, если CX = -1 CX Количество секторов, которое нужно прочитать или -1 DX Начальный относительный сектор __________________________________________________________ Предостережение Пользуйтесь этой функцией только в случае крайней необходимости. Лучше получать доступ к файлам с помощью обычных функций системы. Нет никакой гарантии, что эта функция будет совместима с последующими версиями MS-DOS. __________________________________________________________ Если СХ = -1, то DS:BX содержит адрес блока параметров. Блок параметров API обеспечивает доступ к разделам, большим чем 32 мегабайта. Структура блока параметров: Номер начального сектора dd ? Количество секторов dw ? Буфер обмена с диском dd ? Прерывание 25Н передает управление драйверу устройства и читает с диска в буфер обмена с диском количество секторов, указанное в СХ. Это прерывание аналогично прерыванию 26Н (Записать на диск абсолютно), только действует в обратном направлении. Учитывая то, что эта процедура не проверяет досконально данные, которые вы помещаете в блок параметров, ваша небрежность может привести к непредсказуемым последствиям. __________________________________________________________ Примечание В ходе прерывания разрушаются все регистры, за исключением сегментных. Сохраняйте все необходимые вашей программе регистры перед организацией прерывания. __________________________________________________________ В момент прерывания система помещает регистр - 30 - флагов в стэк . Он находится там и по возвращении. Для предотвращения неконтролируемого роста стэка, не забывайте его выбирать при возврате в вызвавший процесс. Если операция с диском прошла успешно, то CF = 0. В противном случае CF(флаг переноса) равен единице, а AL содержит код ошибки. Макроопределение: abs-disk-read macro disk,buffer,num-sectors,ferst-sector mov al,disk mov bx,offset buffer mov cx,num-sectors mov dx,first-sector int 25H popf endm Пример: Эта программа копирует содержимое одностороннего диска в дисководе А на диск в дисководе В. prompt db "Источник в А, адресат в В",0DH,0AH db "Нажать любую клавишую.$" first dw 0 buffer db 60 dup (512 dup (?)) ; 60 Секторов ; begin: display prompt ; См. функцию 09Н read-kbd ; См. функцию 08Н mov cx,6 ; Копировать 6 групп ; по 60 секторов copy: push cx ; Сохранить счетчик циклов abs-disk-read 0,buffer,60,first ; Наше прерывание abs-disk-write 1,buffer,60,first ; См. прерывание ; 26Н add first,60 ; Следующие 60 секторов pop cx ; Счетчик цикла восстановить loop copy Следующий пример программы читает абсолютный сектор используя прерывание 25Н: mov al,'C'-'A' ; Выбрать дисковод С: mov cx,-1 ; Новый формат mov bx,code ; DS:BX адресует блок mov ds,bx ; параметров, который опре- ; деляет номер сектора, ; количество секторов и ; буфер обмена с диском mov bx,par-pck int 25H ; Выполнить операцию jc error-on-read ; Проверка на код ошибки par-pck: dd 12345H ; Номер абсолютного сектора dw 2 ; Количество секторов dd buffer ; Буфер обмена buffer db 1024 dup (0) ; Адресат считывания - 31 - ЗАПИСАТЬ НА ДИСК АБСОЛЮТНО (ПРЕРЫВАНИЕ 26Н) Вызов: AL - номер дисковода DS:BX - буфер обмена с диском или адрес блока параметров, если СХ = -1 СХ - количество секторов или -1 DX - начальный относительный сектор Возвращает: AL - код ошибки, если CF = 1 FLAGS CF = 0 если операция завершена успешно = 1 сбой Комментарий: __________________________________________________________ Предостережение Пользуйтесь этой функцией только в случае крайней необходимости. Лучше пользоваться обычными функциями системы, т.к. совместимость этой функции с последующими версиями системы не гарантируется . __________________________________________________________ Регистры должны содержать следующие значения: Регистр Содержимое __________________________________________________________ AL Номер дисковода ( 0=А, 1=В и т.д.) DS:BX Смещение буфера обмена с диском или адрес блока параметров, если СХ = -1 СХ Количество секторов, которые необходимо записать или -1 DX Начальный относительный сектор __________________________________________________________ Это прерывание передает управление системе. Из буфера обмена с диском на диск записывается количество секторов, указанное в СХ. Правильность данных, вводимых вами в блок параметров не проверяется , поэтому ваша небрежность может привести к непредсказуемым последствиям. Структура блока параметров: Номер начального сектора dd ? Количество секторов dw ? Буфер обмена с диском dd ? __________________________________________________________ Примечание Это прерывание разрушает все регистры, кроме сегментных . Не забывайте сохранять регистры перед вызовом прерывания. __________________________________________________________ Во время прерывания система помещает регистр флагов в стэк. Он остается в стэке и по возвращении из прерывания. Для предотвращения неконтролируемого роста стэка не забывайте его выбирать по возвращении . При успешной операции с диском CF = 0, в противном случае CF равен 1, а AL содержит код ошибки ( См. прерывание 24Н, коды и их значения). - 32 - Макроопределение: abs-disk-write macro disk,buffer,num-sectors,first-sector mov al,disk mov bx,offset buffer mov cx, num-sectors mov dx,first-sector int 26H popf endm Пример: Следующая программа копирует содержимое одностороннего диска в дисководе А на диск в дисководе В, проверяя каждую запись. Программа использует буфер в 32 килобайта. off equ 0 on equ 1 ; prompt db "Источник в А, адресат в В",0DH,0AH db "Нажмите любую клавишу. $" first dw 0 buffer db 60 dup (512 dup (?)) ; 60 секторов ; begin: display prompt ; См. функцию 09Н read-kbd ; См. функцию 08Н verify on ; См. функцию 2ЕН mov cx,6 ; Копировать 6 групп ; по 60 секторов copy: push cx ; Сохранить счетчик цикла abs-disk-read 0,buffer,60,first ; См. прерывание ; 25Н abs-disk-write 1,buffer,60,first ; Наше прерывание add first,60 ; Следующие 60 секторов pop cx ; Восстановить счетчик цикла loop copy verify off ; См. функцию 2ЕН Следующий пример - чтение абсолютного сектора с помошью прерывания 26Н: mov al,'C'-'A' ; Выбрать дисковод С: mov cx,-1 ; Выбрать новый формат mov bx,code ; DS:BX адресуют блок mov ds,bx ; параметров, содержащий mov bx,offset par-pck ; номер сектора, коли- ; чество секторов и буфер ; обмена с диском int 26H ; Выполнить операцию jc error-on-write ; Проверка на ошибку par-pck: dd 12345H ; Номер абсолютного сектора dw 2 ; Количество секторов для ; чтения dd buffer ; Буфер обмена buffer db 1024 dup (0) ; Буфер для записи - 33 - ЗАКОНЧИТЬ, НО СОХРАНИТЬ В ПАМЯТИ (ПРЕРЫВАНИЕ 27Н) Вызов: CS:DX - указатель на первый байт, следующий за последним байтом кода Возвращает: -- Комментарий: Это прерывание введено в систему только для обеспечения совместимости с версиями MS-DOS до 2.0. В остальных случаях лучше пользоваться функцией 31Н ( Сохранить программу ). Кроме того, функция 31Н позволяет сохранять в памяти программы, размер которых превышает 64 килобайта и возвращает код возврата. Обычно прерывание 27Н используется для передачи управления процедурам обработки прерываний, написанных специально для обслуживания устройств и, размер которых не превышает 64К. DX должен содержать смещение первого байта, следующего за последним байтом кода программы ( сегментный адрес в CS). При выполнении прерывания 27Н , программа прерывается и управление передается системе, но на эту программу не может быть наложена другая программа. Файлы остаются открытыми. На момент прерывания CS должен содержать сегментный адрес префикса сегмента кодов (PSP). .Exe программы, занимающие большую память не должны использовать это прерывание. Также нельзя использовать прерывание 27Н для сохранения процедур обработки прерываний по CONTROL+C и по критической ошибке, т.к. оно восстанавливает вектора прерываний 22Н, 23Н и 24Н. Макроопределение: stay-resident macro last-instruc mov dx,offset last-instruc inc dx int 27H endm Пример: Так как большинство применений прерывания 27Н связано со специфичными процедурами обслуживания устройств, приводить общий пример не целесообразно. - 34 - 1.12 ФУНКЦИИ Ниже приводися описание функций 00Н-68Н. ЗАКОНЧИТЬ ПРОГРАММУ ( ФУНКЦИЯ 00Н ) Вызов: АН = 00Н CS - сегментный адрес префикса сегмента кодов (PSP) Возвращает: -- Комментарий: Функция 00Н выполняет те же действия, что и прерывание 20Н. Она прерывает текущую программу и передает управление вызвавшей программе. Кроме того, закрываются все открытые файлы и очищается буфер обмена с диском. На момент прерывания CS должен содержать сегментный адрес PSP. Адреса следующих процедур прерывания восстанавливаются из PSP: Смещение в PSP Процедура выхода __________________________________________________________ 0АН Программу закончить 0ЕН CONTROL+C 12Н Критичесакя ошибка __________________________________________________________ Все буферы файлов сносятся на диск. __________________________________________________________ Предостережение Не забудте закрыть все файлы, которые вы изменяли перед вызовом этой функции. Иначе длина файла будет записана в каталог не правильно. См. функцию 10Н. __________________________________________________________ Макроопределение: terminate-program macro xor ah,ah int 21H endm Пример: Следующая программа выводит сообщение и передает управление системе. Она использует только открывающую часть скелета программы примера, показанной на рис. 1.2. message db "Пример использования func00H",0DH,0AH,"$" ; begin: display message ; См. функцию 09Н terminate-program ; Наша функция code ends end start ЧИТАТЬ С КЛАВИАТУРЫ И ЭХО ( ФУНКЦИЯ 01Н ) Вызов: АН = 01Н - 35 - Возвращает: AL - введенный символ Комментарий: Функция ожидает ввода символа со стандартного ввода, затем выдает эхо-символ на стандартный вывод и возвращает его в регистре AL. При вводе CONTROL+C, выполняется прерывание 23Н. Макроопределение: read-kbd-and-echo macro mov ah,01H int 21H endm Пример: Следующая программа отображает и выводит на печать введенные с клавиатуры символы. При нажатии ВВОД, программа посылает последовательность ПС/ВК как на экран, так и на принтер. begin: read-kbd-and-echo ; Наша функция print-char al ; См. функцию 05Н cmp al,0DH ; Это ВК ? jne begin ; Нет, печатать print-char 0AH ; См. функцию 05Н diaplay-char 0AH ; См. функцию 02Н jmp begin ; Получить следующий символ ОТОБРАЗИТЬ СИМВОЛ ( ФУНКЦИЯ 02Н ) Вызов: АН = 02Н DL - отображаемый символ Возвращает: -- Комментарий: Функция 02Н символ из регистра DL на стандартный вывод. При нажатии CONTROL+C вызывается прерывание 23Н. Макроопределение: display-char macro character mov dl,character mov ah,02H int 21H endm Пример: Следующая программа преобразует символы нижнего регистра по верхнему регистру и выводит их на экран. begin: read-kbd ; См. функцию 08Н cmp al,"a" jl uppercase ; Не преобразовывать cmp al,"z" jg uppercase ; Не преобразовывать sub al,20H ; Преобразовать к коду ; ASCII по верхнему ; регистру uppercase: display-char al ; Наша функция jmp begin ; Получить следующий ; символ - 36 - ДОПОЛНИТЕЛЬНЫЙ ВВОД ( ФУНКЦИЯ 03Н ) Вызов: АН = 03Н Возвращает: AL - символ из дополнительного устройства Комментарий: Функция 03Н ждет символа из дополнительного устройства ( AUX, COM1, COM2, COM3, COM4 ) и возвращает его в регистре AL. Эта функция не возвращает кодов состояния или ошибок. При нажатии CONTROL+C вызывается прерывание 23Н. Макроопределение: aux-input macro mov ah,03H int 21H endm Пример: Следующая программа выводит на печать символы, поступающие с дополнительного устройства. Печать прекращается при поступлении символа-признака конца файла ( ASCII 26 или CONTROL+Z ). begin: aux-input ; Наша функция cmp al,1AH ; Конец файла ? je return ; ДА, закончить print-char al ; См. функцию 05Н jmp begin ; Получить следующий символ ДОПОЛНИТЕЛЬНЫЙ ВЫВОД ( ФУНКЦИЯ 04Н) Вызов: АН = 04Н DL - Символ для дполнительного устройства Возвращает: -- Комментарий: Функция 04Н посылает символ из регистра DL на стандартное устройство вывода. Эта функция не возвращает коды состояния или ошибок. При нажатии CONTROL+C вызывается прерывание 23Н. Макроопределение: aux-output macro character mov dl,character mov ah,04H int 21H endm Пример: Следующая программа читает с клавиатуры серию строк до 80 - 37 - байт каждая и посылает их на дополнительное устройство. Возврат - при получении символа ВК ( Нулевая строка ) string db 81 dup (?) ; begin: get-string 80, string ; См. функцию 0АН cmp string[1],0 ; Нулевая строка? je return ; Да, закончить mov cx,word ptr string[1] ; Получить длину ; строки mov bx,0 ; Сбросить индекс в ноль send-it: aux-output string[bx+2] ; Наша функция inc bx ; Увеличить индекс loop send-it ; Получить следующую jmp begin ; строку ПЕЧАТАТЬ СИМВОЛ ( ФУНКЦИЯ 05Н ) Вызов: АН = 05Н DL - символ для принтера Возвращает: -- Комментарий: Функция 05Н посылает символ из регистра DL на принтер. При нажатии CONTROL+C вызывается прерывание 23Н. Эта функция не возвращает кодов состояния или ошибки. Макроопределение: print-char macro character mov dl,character mov al,05H int 21H endm Пример: Следующая программа делает тестовую распечатку. Возврат - при нажатии CONTROL+C. line-num db 0 ; begin: mov cx,60 ; Печатать 60 строк start-line: mov bl,33 ; Первый печатный ; символ ASCII add bl,line-num ; Сместить на один символ push cx ; Сохранить счетчик строк mov cx,80 ; Счетчик цикла для строки print-it: print-char bl ; Наша функция inc bl ; Следующий символ ASCII cmp bl,126 ; Последний печатный ; символ ASCII jl no-reset ; Входит? mov bl,33 ; Начать по-новой с (!) no-reset: loop print-it ; Распечатать print-char 0DH ; ВК print-char 0AH ; ПС - 38 - inc line-num ; Для смещения к следующему ; символу pop cx ; Восстановить счетчик строк loop start-line; Распечатать следующую строку ПРЯМОЙ ВВОД/ВЫВОД С КОНСОЛИ ( ФУНКЦИЯ 06Н ) Вызов: АН = 06Н DL - См. текст Возвращает: AL - Если DL перед вызовом функции был равен FFH, то сброс флага переноса означает, что в AL содержится символ со стандартного ввода. Установка CF означает, что такого символа не было и AL = 0. Комментарий: Действие функции 06Н зависит от содержимого регистра DL: Значение DL Действие __________________________________________________________ FFH Если символ был прочитан со стандартного ввода, то он возвращается в AL, а CF сбрасывается (0). Если символ не был прочитан, то CF устанавливается (1). Любое, кроме Символ из регистра DL посылается на FFH стандартный вывод. __________________________________________________________ Эта функция не делает проверку по CONTROL+C Макроопределение: dir-console-io macro switch mov dl,switch mov ah,06H int 21H endm Пример: Следующая программа сбрасывает системные часы и непрерывно отображает время . При вводе любого символа,экран "замирает"; при повторном вводе любого символа, часы опять сбрасываются и отбражение начинается с нуля. time db "00:00:00.00",0DH,0AH,"$" ; Смысл $ - ; ; см. функцию 09Н begin: set-time 0,0,0,0 ; См. функцию 2DH read-clock: get-time ; См. функцию 2СН CONVERT ch,time ; См. конец главы CONVERT cl,time[3] ; См. конец главы CONVERT dh,time[6] ; См. конец главы CONVERT dl,time[9] ; См. конец главы display time ; См. функцию 09Н dir-console-io FFH ; Наша функция cmp al,0 ; Символ введен? jne stop ; ДА, стоп таймер jmp read-clock ; Нет, продолжить - 39 - ; индикацию stop: read-kbd ; См. функцию 08Н jmp begin ; Все с начала ПРЯМОЙ ВВОД С КОНСОЛИ ( ФУНКЦИЯ 07Н ) Вызов: АН = 07Н Возвращает: AL - символ с клавиатуры Комментарий: Функция 07Н ждет ввода символа со стандартного ввода и возвращает его в AL. Эта функция не дает эхо-символа и не проверяет по CONTROL+C. Если вам необходимы эти дополнения, выбирете соответствующую функцию - 01Н или 08Н. Макроопределение: dir-console-input macro mov ah,07H int 21H endm Пример: Следующая программа делает запрос на пароль (не более 8 символов) и помещает введенные символы в стоку без эха. password db 8 dup (?) prompt db "Password: $" ; Об'яснение $ - ; ; см. функцию 09Н begin: display prompt ; См. фнкцию 09Н mov cx,8 ; Макс. длина пароля xor bx,bx ; BL может служить ; индексом get-pass: dir-console-input ; Наша функция cmp al,0DH ; Это ВК ? je return ; Да, возврат mov password[bx],al ; Нет, поместить ; символ в строку inc bx ; Прирастить индекс loop get-pass ; Следующий символ ЧИТАТЬ С КЛАВИАТУРЫ ( ФУНКЦИЯ 08Н ) Вызов: АН = 08Н Возврат: AL - символ с клавиатуры Комментарий: Функция 08Н ждет символ с клавиатуры и возвращает его в AL. При нажатии CONTROL+C вызывается прерывание 23Н. Эта функция не дает эхо-символа ( См. функцию 01Н, если вам нужно, чтобы была проверка на CONTROL+C и выводился эхо символ). - 40 - Макроопределение: read-kbd macro mov ah,08H int 21H endm Пример: См. пример из функции 07Н. ОТОБРАЗИТЬ СТРОКУ ( ФУНКЦИЯ 09Н ) Вызов: АН = 09Н DS:DX - указатель на отображаемую строку Возвращает: -- Комментарий: Функция посылает на стандартный вывод строку. $ - признак конца строки. $ не отображается. DX должен содержать смещение строки (сегментный адрес в DS). Макроопределение: display macro string mov dx,offset string mov ah,09H int 21H endm Пример: Следующая программа выводит на экран шестнадцатеричный код нажимаемых клавиш. table db "01234556789ABCDEF" result db "- 00H",0DH,0AH,"$" begin: read-kbd-and-echo ; См. функцию 01Н xor ah,ah ; Сброс старшего байта convert ax,16,result[3] ; См. конец главы display result ; Наша функция jmp begin ; По новой ВВОД С КЛАВИАТУРЫ ЧЕРЕЗ БУФЕР ( ФУНКЦИЯ 0АН ) Вызов: АН = 0АН DS:DX - указатель на буфер ввода Возвращает: -- Комментарий: Функция читает строку со стандартного ввода. DX должен содержать смещение ( сегментный адрес в DS ) буфера ввода, который имеет следующую структуру: - 41 - байт Содержимое __________________________________________________________ 1 Максимальное количество символов в буфере, включая ВК ( вы устанавливаете этот байт ). 2 Количество введенных символов реально, без ВК ( функция устанавливает этот байт ). 3-n Буфер, длиной не меньше величины, указанной в первом байте. __________________________________________________________ Символы читаются со стандартного ввода и помещаются в буфер, начиная с третьего байта. ENTER тоже читается ( ВВОД ). Когда буфер заполнен без одного символа, следующие символы не читаются, а на стандартный вывод посылается ASCII 07Н (Звонок) до тех пор, пока не будет введен символ ВВОД. При вводе, строку можно редактировать. При вводе CONTROL+C вызывается прерывание 23Н. Макроопределение: get-string macro limit,string mov dx,offset string mov string,limit mov ah,0AH int 21H endm Пример: Следующая программа читает 16-байтовую (максимум) строку с клавиатуры и заполняет ею экран в 24 строки по 80 символов. buffer label byte max-length db ? ; Макс. длина chars-entered db ? ; Кол-во символов string db 17 dup (?) ; 16 симв. + ВК strings-per-line dw 0 ; Сколько строк ; помещается в ; строке экрана crlf db 0DH,0AH ; begin: get-string 17,buffer ; Наша функция xor bx,bx ; Использовать ; как индекс mov bl,chars-entered ; Получить длину ; строки mov buffer[bx+2],"$" ; См. функцию 09Н mov al,50H ; Кол-во колонок ; в стоке экрана cbw div chars-entered ; Сколько раз ; введенная строка ; входит в строку ; экрана xor ah,ah ; Сбросить остаток mov strings-per-line,ax ; Сохранить ; счетчик колонок mov cx,24 ; Счетчик рядов display-screen: push cx ; Сохранить его mov cx,strings-per-line ; Загрузить ; счетчик колонок - 42 - display-line: display string ; См. функцию 09Н loop display-line ; display crlf ; См. функцию 09Н pop cx ; Восстановить ; счетчик рядов loop display-screen ; Отобразить еще ; один ряд ОПРОС СОСТОЯНИЯ КЛАВИАТУРЫ ( ФУНКЦИЯ 0ВН ) Вызов: АН = 0ВН Возвращает: AL - 00Н= если нет символов в буфере клавиатуры FFH= есть символы в буфере клавиатуры Комментарий: Функция 0ВН проверяет, есть ли в буфере клавиатуры символы со стандартного ввода (если стандартный ввод не был переадресован, то опрашивается буфер клавиатуры). Если таковые есть, то AL возвращает FFH, в противном случае - 00Н. Если в буфере CONTROL+C, то вызывается прерывание 23Н. Макроопределение: check-kbd-status macro mov ah,0BH int 21H endm Пример: Следующая программа непрерывно отображает время до нажатия любой клавиши: time db "00:00:00.00",0DH,0AH,"$" . . begin: 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Н check-kbd-status ; Наша функция cmp al,0FFH ; Есть символы? je return ; Да, возврат jmp begin ; Нет, продолжать ; индикацию времени ОЧИСТИТЬ БУФЕР, ЧИТАТЬ С КЛАВИАТУРЫ ( ФУНКЦИЯ 0СН ) Вызов: АН = 0СН AL - 1,6,7,8 или 0АН = вызывается соответствующая функция - любое другое значение = никаких последующих действий - 43 - Возвращает: AL - 00Н = буфер клавиатуры очищен и никаких последующих действий Комментарий: Функция 0СН очищает стандартный буфер ввода (если не переназначен, то буфер клавиатуры). Дальнейшие действия зависят от содержимого AL. AL Действия __________________________________________________________ 1,6,7,8 или 0АН Вызывается соответствующая функция MS-DOS. Любое другое Никаких последующих действий, AL возвра- значение щает 00Н. __________________________________________________________ Макроопределение: flush-and-read-kbd macro switch mov al,switch mov al,0CH int 21H endm Пример: Следующая программа отображает на экране и выводит на печать символы, которые вы вводите с клавиатуры. При нажатии ВВОД, на экран и на принтер посылается последовательность ВК/ПС. begin: flush-and-read-kbd 1 ; Наша функция print-char al ; См. функцию 05Н cmp al,0DH ; Это ВК ? jne begin ; Нет, печатать print-char 0AH ; См. функцию 05Н display-char 0AH ; См. функцию 02Н jmp begin ; Следующий символ СБРОС ДИСКА ( ФУНКЦИЯ 0DH ) Вызов: АН = 0DH Возвращает: -- Комментарий: Функция очищает все буферы файлов для уверенности, что системное каше соответствует дискам в дисководах. Она стирает все буферы, которые модифицировались и отмечает как свободные все буферы системного каше. Эта функция обычно используется для введения системы в привычное состояние. Процедурам обслуживания прерывания по CONTROL+C желательно использовать эту функцию. Эта функция не обновляет входы каталогов. Вам необходимо закрыть измененные файлы перед вызовом этой функции ( См. функцию 10Н, Закрыть файл). - 44 - Макроопределение: reset-disk macro mov ah,0DH int 21H endm Пример: Следующая программа очищает все буферы файлов и выбирает дисковод А. begin: reset-disk select-disk "A" ВЫБОР ДИСКА ( ФУНКЦИЯ 0ЕН ) Вызов: АН = 0ЕН DL - номер логического дисковода ( 0=А, 1=В и т.д. ) Возвращает: AL - количество логических дисководов Комментарий: Функция 0ЕН выбирает дисковод, указанный в регистре DL в качестве текущего логического дисковода. AL возвращает количество логических дисководов. __________________________________________________________ Примечание Для обеспечения совместимости ваших программ с будущими версиями системы, осторожно относи- тесь к значению, возвращаемому в AL. Например, если AL возвращает 5, то не безопасно исходить из того, что A,B,C,D и Е - все активные дисководы. __________________________________________________________ Макроопределение: select-disk macro disk mov dl,disk[-64] mov ah,0EH int 21H endm Пример: Следующая программа переключается между дисководами А и В для выбора текущего диска ( в системе с двумя дисководами). begin: current-disk ; См. функцию 19Н cmp al,00H ; Дисковод А: выбран? je select-b ; Да, выбрать В select-disk "A" ; Наша функция jmp return ; select-b select-disk "B" ; Наша функция - 45 - ОТКРЫТЬ ФАЙЛ ( ФУНКЦИЯ 0FH ) Вызов: АН = 0FH DS:DX - указатель на неоткрытый FCB Возвращает: AL - 00H = вход каталога найден FFH = вход каталога не найден Комментарий: Функция 0FH открывает файл. DX должен содержать смещение (сегментный адрес в DS ) блока управления файлом (FCB). Эта функция ищет в каталоге диска указанное имя файла. Если она находит вход каталога для файла, то AL возвращает 0, а FCB заполняется следующим образом: - Если код накопителя был 0 (текущий дисковод), то он заменяется на код реально использованного дисковода. Это позволяет вам сменить текущий дисковод без последущего вмешательства в операции с файлом. - Текущий блок (смещение 0СН) сбрасывается в 0. - Размер записи (смещение 0ЕН) устанавливается по умолчанию - 128. - Размер файла (смещение 0FH), Дата последней записи (смещение 14Н) и Время последней записи (смещение 16Н) устанавливаются из входа каталога. Перед операцией последовательного чтения с диска, вам необходимо выставить поле Текущей записи (смещение 20Н), при выборочном доступе - поле Относительной записи (смещение 21Н). Если длина записи по умолчанию (128) вас не устраивает, измените поле Размер записи. Если каталоговый вход для файла не найден, или файл имеет атрибуты скрытый или системный, то AL возвращает FFH. Макроопределение: open macro fcb mov dx,offset fcb mov ah,0FH int 21H endm Пример: Следующая программа выводит на печать файл с именем textfile.asc, находящийся на диске в дисководе В. Последняя запись печатается до получения символа конец-файла ( ASCII 26 или CONTROL+Z ). fcb db 2,"TEXTFILEASC" db 26 dup (?) buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН open fcb ; Наша функция read-line: read-seq fcb ; См. функцию 14Н cmp al,02H ; Конец файла? je all-done ; Да, возврат cmp al,00H ; Еще? jg check-more ; Нет, проверка на ; последнюю запись mov cx,80H ; Да, печатать буфер - 46 - xor si,si ; Сброс индекса print-it: print-char buffer[si] ; См. функцию 05Н inc si ; Увеличить индекс loop print-it ; Печатать следующий ; символ jmp read-line ; Читать другую запись check-more: cmp al,03H ; Читать последнюю ? jne all-done ; Нет mov cx,80H ; Да, печатать xor si,si ; Сброс индекса find-eof: cmp buffer[si],26 ; Признак конца файла? je all-done ; Да print-char buffer[si] ; См. функцию 05Н inc si ; Инкремент индекса loop find-eof ; на след. символ all-done: close fcb ; См. функцию 10Н ЗАКРЫТЬ ФАЙЛ ( ФУНКЦИЯ 10Н ) Вызов: АН = 10Н DS:DX - указатель на открытый FCB Возвращает: AL - 00Н = каталоговый вход найден FFH = каталоговый вход не найден Комментарий: Функция 10Н закрывает файл. DX должен содержать cмещение (сегментный адрес в DS) открытого FCB. Функция ищет c каталоге файл c именем , указанным в FCB. После этого каталоговый вход приводится в соответствие, если необходимо, блоку управления файлом, а AL возвращает 0. После изменения файла, вам необходимо вызвать эту функцию для обновления каталогового входа. Лучше закрывать любой файл (даже тот, который не менялся), в доступе к которому вы больше не нуждаетесь. Если каталоговый вход для файла не найден, AL возвращает FFH. Макроопределение: close macro fcb mov dx,offset fcb mov ah,10H int 21H endm Пример: Следующая программа проверяет первый байт файла с именем mod1.bas в дисководе В на значение FFH, и при равенстве выводит сообщение. message db "Хранится не в ASCII формате",0DH,0AH,"$" fcb db 2,"MOD1 BAS" db 26 dup (?) buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН open fcb ; См. функцию 0FH read-seq fcb ; См. функцию 14Н - 47 - cmp buffer,0FFH ; Первый байт - FFH ? jne all-done ; Нет display message ; См. функцию 09Н all-done: close fcb ; Наша функция ИСКАТЬ ПО ПЕРВОМУ ВХОДУ ( ФУНКЦИЯ 11Н ) Вызов: АН = 11Н DS:DX - указатель на неоткрытый FCB Возвращает: AL - 00Н = каталоговый вход найден FFH = каталоговый вход не найден Комментарий: Функция ищет в каталоге диска указанное имя файла. В DX содержится смещение (сегментный адрес в DS) не открытого FCB. Имя файла в блоке FCB может иметь символы заменители. Для поиска скрытого или системного файла, DX должен адресовать первый байт префикса расширенного FCB. Если эта функция не находит каталоговый вход для имени файла , указанного в FCB, AL возвращает FFН. Если функция находит такой вход, AL возвращает 0 и в буфере обмена с диском создается такой-же неоткрытый FCB следующего формата: 1. Если FCB был нормальным, то первый байт буфера обмена с диском устанавливается равным номеру накопителя, использованного в поиске (1=А, 2=В и т.д.), а следующие 32 байта содержат каталоговый вход. 2. Если FCB был расширенным, то первый байт буфера обмена с диском устанавливается в FFH, следующие 5 байт обнуляются, а следующий байт принимает значение байта атрибута в искомом FCB. Оставшиеся 33 байта устанавливаются также, как и при нормальном FCB. Если вы используете функцию 12Н (Искать по следующему входу) для продолжения поиска, вам нет необходимости создавать альтернативный или по-новой открывать блок FCB. Поле атрибута это последний байт расширенного FCB, предшествующего обычному (См. Раздел 1.9.1) FCB. Если это поле равно нулю, то функция ищет только обычные файлы. Она не осуществляет поиск скрытых и системных файлов, файлов с атрибутом ТОМ и подкаталогов. Если поле атрибута идентифицирует скрытый, системный файлы или подкаталог ( 02Н, 04Н или 10Н ) или любую комбинацию этих значений, то функция по-прежнему ищет обычные файлы. Установите байт атрибута в 16Н, если вы не хотите, чтобы искались файлы с атрибутом ТОМ. Если байт атрибута равен 08Н (метка тома), то функция ищет только такие файлы. Макроопределение: search-first macro fcb mov dx,offset fcb mov ah,11H int 21H endm - 48 - Пример: Следующая программа проверяет существование файла с именем report.asm на диске в дисководе В. yes db "ФАЙЛ СУЩЕСТВУЕТ.$" no db "ФАЙЛ НЕ СУЩЕСТВУЕТ.$" crlf db 0DH,0AH,"$" db 2,"report asm" db 26 dup (?) buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН search-first fcb ; Наша функция cmp al,0FFH ; Каталоговый вход найден? je not-there ; Нет display yes ; См. функцию 09Н jmp continue ; not-there: display no ; См. функцию 09Н continue: display crlf ; См. функцию 09Н ИСКАТЬ ПО СЛЕДУЮЩЕМУ ВХОДУ ( ФУНКЦИЯ 12Н ) Вызов: АН = 12Н DS:DX - указатель на неоткрытый FCB Возвращает: AL - 00H = каталоговый вход найден FFH = каталоговый вход не найден Комментарий: После использования функции 11Н, вы можете применить функцию 12Н для поиска других входов, удовлетворяющих имени файла (содержащего символы заполнители). DX должен содержать смещение (сегментный адрес в DS ) FCB, указанного в предыдущем вызове функции 11Н. Для поиска системных или скрытых файлов, DX должен содержать указатель на первый байт префикса расширенного FCB, содержащего в свою очередь соответствующее значение атрибута. Если поиск неудачен, AL возвращает FFH. В противном случае в AL - 00H, а функция создает такой-же FCB (обычный или расширенный) в буфере обмена с диском ( подробнее, см. функцию 11Н). Макроопределение: search-next macro fcb mov dx,offset fcb mov ah,12H int 21H endm Пример: Следующая программа выводит на экран количество файлов на диске В. message db "Нет файлов",0DH,0AH,"$" files db 0 fcb db 2,"???????????" db 26 dup (?) - 49 - buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН search-first fcb ; См. функцию 11Н cmp al,0FFH ; Каталоговый вход найден? je all-done ; Нет, нет файлов inc files ; Да, увеличить счетчик search-dir: search-next fcb ; Наша функция cmp al,0FFH ; Каталоговый вход найден? je done ; Нет inc files ; Да, инкремент счетчика jnp search-dir ; По-новой done: convert files,10,message ; См. конец главы all-done: display message ; См. функцию 09Н УДАЛИТЬ ФАЙЛ ( ФУНКЦИЯ 13Н ) Вызов: АН = 13Н DS:DX - указатель на неоткрытый FCB Возвращает: AL - 00H = каталоговый вход найден FFH = каталоговый вход не найден Комментарий: Функция 13Н удаляет файл. DX должен содержать смещение (сегментный адрес в DS) неоткрытого FCB. Имя файла в FCB может содержать символы заполнители. Если соответствующий вход не найден, то AL возвращает FFH. При удачном поиске AL равно 0, а из каталога удаляется соответствующий вход. Если имя содержит символы заполнители, то удаляются все файлы, имена которых подходят. Не удаляйте открытые файлы. Макроопределение: delete macro fcb mov dx,offset fcb mov ah,13H int 21H endm Пример: Следующая программа удаляет все файлы с диска В, последняя запись в которые делалась до 31 Декабря 1982 года. year dw 1982 month db 12 day db 31 files db 0 message db "Удаленных файлов нет.".0DH,0AH,"$" fcb db 2,"???????????" db 26 dup (?) buffer db 128 dup (?) ; begin: set-dta buffer ; См. функцию 1АН search-first fcb ; См. функцию 11Н cmp al,0FFH ; Каталоговый вход найден? jne compare ; Да - 50 - jmp all-done ; Нет, нет файлов на диске compare: convert-date buffer ; См. конец главы cmp cx,year ; Следующие строки сравни- jg next ; вают дату в каталоговом cmp dl,month ; входе с указанной . jg next cmp dh,day jge next delete buffer ; Наша функция inc files ; Увеличить счетчик ; файлов next: search-next fcb ; См. функцию 12Н cmp al,00H ; Каталоговый вход найден? je compare ; Да, проверить дату cmp files,0 ; Есть удаленные файлы? je all-done ; Нет, сообщить об этом convert files,10,message ; См. конец главы all-done: display message ; См. функцию 09Н © KOAP Open Portal 2000 |