ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.


Только у нас козырьки из поликарбоната недорого, со скидками.
КАК ЧИТАТЬ ДИСК АБСОЛЮТНО (ПРЕРЫВАНИЕ 25Н)

     Вызов:         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



?????? ???????????