Недокументированные возможности MS-DOS - Альтернативный обработчик прерывания int 21h

Альтернативный обработчик прерывания int 21h

Альтернативный обработчик прерывания 21h предъявляет другие требования к входным параметрам, чем обычный вызов INT 21h. Его использование требует некоторых специальных действий и понимания того, что он позволяет.

Прежде всего, обработчик ожидает, что адрес возврата будет в стеке в отличном от обычного порядке. Обычно, когда генерируется прерывание, процессор сначала заносит в стек флаги, а затем сегмент и смещение адреса возврата. Однако в этой точке входа предполагается, что флаги были занесены в стек последними, после занесения смещения и сегмента адреса возврата.

Назначение команд, находящихся в этой точке входа - выполнить некоторую предварительную обработку входных данных и стека, прежде чем передать управление стандартному обработчику прерывания 21h. Иными словами, альтернативный обработчик прерывания является лишь надстройкой над стандартным. Поэтому первое, что он делает - это перестраивает стек в стандартном порядке, приемлемом для команды IRET.

Следующим действием альтернативный обработчик прерывания 21h контролирует номер запрашиваемой для выполнения функции и допускает только функции с номерами 00h-24h. Поскольку регистр AX разрушается сразу же после входа, номер функции передается в регистре CL, а не в AH. Это же означает, что даже среди допустимых функций есть недоступные: те, которые требуют дополнительного параметра в регистре AL. Так, например, недоступна функция 0Ch (очистить буфер клавиатуры и затем вызвать одну из функций 01h, 06h, 07h, 08h, или 0Ah), поскольку она требует номер подфункции в регистре AL.

Однако как узнать, где располагается этот обработчик прерывания, чтобы получить к нему доступ? Вектор прерывания 30h содержит команду JMP FAR, позволяющую перейти по требуемому адресу. Таким образом, чтобы использовать прямой вызов DOS, вызывающая программа должна занести в стек сначала флаги, затем смещение и сегмент адреса возврата, а потом загрузить в регистр CL номер функции и выполнить далекий переход по адресу 0:00C0, передав таким образом управление альтернативному обработчику прерывания 21h. По окончании функционирования обработчик прерывания 21h выполняет команду IRET по адресу возврата, находящемуся, как обычно, в стеке.

Остается выяснить вопрос: для чего вообще нужен альтернативный обработчик прерывания 21h, почему к нему такой необычный способ доступа и отчего в нем такое странное соглашение о входных параметрах. На все эти три вопроса можно ответить одновременно: это связано с желанием разработчиков MS-DOS обеспечить совместимость с операционной системой CP/M, господствовавшей до появления MS-DOS. Поэтому соглашение о входных параметрах и ограниченность выбора функций, столь странные для пользователей MS-DOS, отнюдь не покажутся странными тем, кто еще помнит CP/M. А что же касается необычного способа доступа к альтернативному обработчику прерывания, то описанный способ в действительности не используется, хотя он вполне корректен, а команда JMP FAR в векторе прерывания 30h существует исключительно для поддержки вызова функций DOS в стиле CP/M через PSP: командой CALL 0005.

Описанный альтернативный обработчик прерывания 21h существует во всех версиях PC-DOS и почти во всех версиях MS-DOS. Интересно заметить, что код этого обработчика, судя по проведенным исследованиям, одинаков во всех версиях DOS и, следовательно, имеет одну и ту же длину. Очевидно, что он является не более чем рудиментом, оставшимся в наследство от операционной системы CP/M, этакий аппендикс MS-DOS. Далее, сегмент DOS, где располагаются все его функции, можно получить многими способами, а смещение в нем альтернативного обработчика прерывания 21h, как, следовательно, и стандартного, одинаково в пределах одной версии DOS, пусть даже и разных фирм.

Можно, конечно, и обойти существующее в этой точке входа ограничение на номер функции. Для этого нужно просто затереть командами NOP проверку на допустимость номера. При этом нельзя упускать из виду другое ограничение: нельзя пользоваться функциями, требующими параметров в регистрах AL и CL.

;----------------------------------------------------------------------------
;        Листинг (срез) альтернативного обработчика прерывания 21h.
;        Текст немного упрощен для лучшей читабельности при
;        сохранении полной смысловой идентичности.
;----------------------------------------------------------------------------

RefuseRequest:                 ; Отказ от выполнения запрашиваемой функции,
        mov  ax, 0              ;     т.к. номер функции недопустим.
        iret

Alt_DOS_Entry:         ; Точка входа в альтернативный обработчик прерывания
        pop     ax              ; Извлечь из стека содержимое регистра флагов
        pop     ax              ; Извлечь из стека сегмент адреса возврата
        pop     cs:Temp         ; Извлечь из стека смещение адреса возврата
                       ; Перестроить стек для команды IRET
        pushf                   ; Сохранить в стеке флаги
        cli                     ; Запретить генерацию прерывания 21h
        push    ax              ; Сохранить сегмент адреса возврата
        push    cs:Temp         ; Сохранить смещение адреса возврата

        cmp     cl, 24h         ; Номер функции меньше максимального?
        ja      RefuseRequest   ; Нет. Отказ обрабатывать запрос.
                       ; Допустимый номер функции.
        mov     ah, cl          ; Загружаем номер функции в AH и переходим
        jmp     short INT_21h_Further   ; в стандартный обработчик INT 21h

INT_21h_Entry:         ; Стандартный обработчик прерывания 21h
        cmp     ah, 6Ch        ; Номер функции меньше максимального?
        ja      RefuseRequest   ; Нет. Отказ обрабатывать запрос.
                       ; Допустимый номер функции.
INT_21h_Further:
        cmp     ah, 51h
        . . .
        . . .
;----------------------------------------------------------------------------

;----------------------------------------------------------------------------
;       Пример вызова функции DOS через альтернативный обработчик
;       прерывания 21h.
;----------------------------------------------------------------------------

               mov     ax, offset RETURN     ; Взять смещение адреса возврата
               push    ax                    ; Занести в стек флаги, сегмент
               push    cs                    ;    и смещение адреса возврата
               pushf                         ;    в обратном порядке.
               mov     cl, 9                 ; Функция: показать строку.
               mov     dx, offset MESSAGE    ; Загрузить адрес сообщения.
               push    cs                    ; Для уверенности, что DS
               pop     ds                    ;    указывает на текущий код.
               jmp     dword ptr ALT_DOS_PTR ; Выполнить функцию.

RETURN:        mov     ah, 4Ch               ; Завершить процесс через DOS.
               int     21h                   ;

ALT_DOS_PTR    dw      00C0h, 0000           ; Адрес для перехода в альтер-
                                            ;    нативный обработчик
MESSAGE        db      0Dh, 0Ah, "Example of backdoor MS-DOS "
               db      "function call.", 0Dh, 0Ah, 7, "$"

;-----------------------------------------------------------------------------

[ Оглавление ]


DOS Fn 00H: завершить программу

Вход

  • AH = 00H
  • CS = сегмент PSP завершающегося процесса

Выход

  • нет = (неприменим)

Описание:

передает управление на вектор завершения в PSP (выходит в родительский процесс). Идентична функции INT 20H Terminate. регистр CS должен указывать на PSP. восстанавливает векторы прерываний DOS 22H-24H (завершение, Ctrl-Break и Критическая ошибка), устанавливая значения, сохраненные в родительском PSP. выполняет сброс файловых буферов. файлы должны быть предварительно закрыты, если их длина изменилась.

Замечание:

Проще и более аккуратно - использовать функцию DOS Fn 4cH Exit.


DOS Fn 01H: ввод с клавиатуры

  • AH = 02H

Выход

  • AL = символ, полученный из стандартного ввода

Описание:

Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). при распознавании Ctrl-Break выполняется INT 23H.

Замечание:

ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и т.п.) требует двух обращений к этой функции. первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.

Комментарии пользователей (всего 5)

indivisible_int / 23 июня 2008, 01:29:39

mov ah,1h
int 21h

да, там в тексте ошибка

MixRin / 21 января 2006, 22:51:56

а такое возможно???,
mov ah, 01h ?????

А почему это невозможно?!

t0x1n / 06 сентября 2005, 23:12:01

Не, все правильно. Вот пример кода:

mov ah,02h
mov al,somvol
int 21h
int 20h

Visualex / 14 июня 2005, 20:39:57

а такое возможно???,
mov ah, 01h ?????

warezhka / 17 ноября 2004, 00:42:18

DOS Fn 01H: ввод с клавиатуры
AH = 02H

- вы не чего не напутали? Может AH = 01H


DOS Fn 02H: вывод на дисплей

  • AH = 02H
  • DL = символ, выводимый на стандартный вывод

Выход

  • нет =

Описание:

Посылает символ из DL на стандартный вывод. обрабатывает символ Backspace (ASCII 8), перемещая курсор влево на одну позицию и оставляя его в новой позиции. при обнаружении Ctrl-Break выполняется INT 23H.

Комментарии пользователей (всего 1)

themind / 09 декабря 2005, 19:08:53

При обработке символа Backspace ничего не стирает, а лишь переводит курсор влево на одну позицию


DOS Fn 03H: Вспомогательный ввод

  • AH = 03H

Выход

  • AL = символ, полученный со стандартного вспомогательного устр-ва

Описание:

Считывает (ожидает) символ со стандартного вспомогательного устройства, COM1 или AUX и возвращает этот символ в AL.

Замечание:

ввод не буферизуется и должен опрашиваться (не управляется прерываниями). при запуске DOS порт AUX (COM1) инициализируется так: 2400 бод, без проверки на четность, 1 стоп-бит, 8-битовые слова. Команда DOS MODE используется для установки иных характеристик.


DOS Fn 04H: Вспомогательный вывод

  • AH = 04H
  • DL = символ, записываемый на стандартное вспомогательное устр-во

Выход

  • нет =

Описание:

Посылает символ в DL на стандартное вспомогательное устройство, COM1 или AUX.


DOS Fn 05H: вывод на принтер

  • AH = 05H
  • DL = символ, записываемый на стандартный принтер

Выход

  • нет =

Описание:

Посылает символ в DL на стандартное устройство принтера, обычно LPT1.

Замечание:

команда DOS MODE может перенаправить этот вывод в последовательный порт.


DOS Fn 06H: Консольный ввод-вывод

  • AH = 06H
  • DL = символ (от 0 до 0feH), посылаемый на стандартный вывод
  • = 0ffH запрос ввода со стандартного ввода

Выход

  • ZF = Сброшен (NZ), если символ готов ҐҐЈҐ при запросе ввода

Описание:

при DL = 0ffH выполняет ввод с консоли "без ожидания", возвращая взведенный флаг нуля (ZF), если на консоли нет готового символа. если символ готов, сбрасывает флаг ZF (NZ) и возвращает считанный символ в AL. если DL не равен 0ffH, то DL направляется на стандартный вывод.

Замечание:

Не проверяет Ctrl-Break. вызывайте дважды для расширенного ASCII.


DOS Fn 07H: Нефильтрующий консольный ввод без эха

  • AH = 07H

Выход

  • AL = символ, полученный через стандартный ввод

Описание:

Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не фильтрует: Не проверяет на Ctrl-Break, backspace и т.п.

Замечаниея:

вызывайте дважды для ввода расширенного символа ASCII. используйте Fn 0bH для проверки статуса (если не хотите ожидать нажатия клавиши).


DOS Fn 08H: Консольный ввод без эха

  • AH = 08H

Выход

  • AL = символ, полученный через стандартный ввод

Описание:

Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. при обнаружении Ctrl-Break выполняется прерывание INT 23H.

Замечание:

вызывайте дважды для ввода расширенного символа ASCII.


DOS Fn 09H: Выдать строку на дисплей

  • AH = 09H
  • DS:DX = адрес строки, заканчивающейся символом '$' (ASCII 24H)

Выход

  • нет =

Описание:

строка, исключая завершающий ее символ '$', посылается на стандартный вывод. символы Backspace обрабатываются как в функции 02H Display Char. обычно, чтобы перейти на новую строку, включают в текст пару CR/LF (ASCII 13H и ASCII 0aH). строки, содержащие '$', можно выдать через 40H Write Handle (BX=0).

Символ CR в таблице ASCII - 0dh


DOS Fn 0aH: ввод строки в буфер

  • AH = 0aH
  • DS:DX = адрес входного буфера (смотри ниже)

Выход

  • нет = буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)

Описание:

при входе буфер по адресу DS:DX должен быть оформлен так:

    +---+---+---+---+---+---+- - -
    ¦max¦ ? ¦ ?   ?   ?   ?   ?     MAX - максимально допустимая
    +---+---+---+---+---+---+ -  -  длина ввода (от 1 до 254)
    при выходе буфер заполнен данными следующим образом:
    +---+---+---+---+---+---+- - -
    ¦max¦len¦ T   E   X   T   0dH   LEN - действительная длина данных
    +---+---+---+---+---+---+ -  -  без завершающего CR (здесь - 04H).

символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter).

Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. последний символ в буфере - всегда CR (который не засчитан в байте длины). символы в буфере (включая LEN) в момент вызова используются как "шаблон". В процессе ввода действительны обычные клавиши редакти рования: Esc выдает "\" и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает "@" и сохраняет текущую строку как шаблон, и т.д. большинство расширенных кодов ASCII игнорируются. при распознавании Ctrl-Break выполняется прерывание INT 23H (буфер остается неизменным).


DOS Fn 0bH: проверить статус ввода

  • AH = 0bH

Выход

  • AL = 0ffH, если символ доступен со стандартного ввода

Описание:

проверяет состояние стандартного ввода. при распознавании Ctrl-Break выполняется INT 23H. Замечения: используйте перед функциями 01H 07H и 08H, чтобы избежать ожидания нажатия клавиши.

Эта функция дает простой неразрушающий способ проверки Ctrl-Break в процессе длинных вычислений или другой обработки, обычно не требующей ввода. это позволяет вам снимать счет по нажатию Ctrl-Break.


DOS Fn 0cH: ввод с очисткой

  • AH = 0cH
  • AL = номер функции ввода DOS (01H, 06H, 07H, 08H или 0aH)

Выход

  • нет =

Описание:

Очищает буфер опережающего ввода стандартного ввода, а затем вызывает функцию ввода, указанную в AL. это заставляет систему ожидать ввод очередного символа. следующие значения допустимы в AL: 01H ввод с клавиатуры

  • 06H ввод с консоли
  • 07H Нефильтрующий без эха
  • 08H ввод без эха
  • 0aH буферизованный ввод


DOS Fn 0dH: Сброс диска

  • AH = 0dH

Выход

  • нет =

Описание:

Сбрасывает (пишет на диск) все файловые буфера. если размер файла изменился, такой файл должен быть предварительно закрыт (при помощи функций 10H или 3eH).


DOS Fn 0eH: установить текущий диск DOS

  • AH = 0eH
  • DL = номер диска (0=A, 1=B и т.д.), который становится текущим

Выход

  • AL = общее число дисководов в системе

Описание:

диск, указанный в DL, становится текущим (умалчиваемым) в DOS. проверка: используйте функцию 19H "дать текущий" для проверки. В регистре AL возвращается число дисководов всех типов, включая твердые диски и "логические" диски (как B: в 1-floppy системе).

Версии:

DOS 3.0+ AL имеет то же значение, что и значение LASTDRIVE, указанное в файле CONFIG.SYS, и по умолчанию равно 5.


DOS Fn 0fH: открыть файл через FCB

  • AH = 0fH
  • DS:DX = адрес неоткрытого FCB

Выход

  • AL = 0 если файл открыт без ошибок (и FCB заполнен)

Описание:

файл, описываемый неоткрытым FCB, должен существовать в текущем оглавлении на диске, специфицированном в FCB (0=текущий, 1=A, 2=B, и т.д.). если файл не существует, возвращается AL=0ffH. файл открывается в режиме совместимости. если поле Drv в FCB равно 0 в момент вызова, то оно заполняется номером текущего дисковода (1=A, 2=B, и т.д.). Поле FCB CurBlk устанавливается в 0. Поле FCB RecSize устанавливается в 80H. Поля даты и размера файла в FCB устанавливаются из оглавления.

Замечание:

функции DOS 2.0+, ориентированные на номер файла (handle), ГОРАЗДО удобнее в работе.


DOS Fn 10H: Закрыть файл через FCB

  • AH = 10H
  • DS:DX = адрес открытого FCB

Выход

  • AL = 0 если файл закрыт без ошибок

Описание:

файл должен находиться на своем первоначальном месте в текущем оглавлении диска, на котором он был открыт. если файл найден, оглавление обновляется, файловые буфера сбрасываются, и возвращается AL=00H. если файл не найден, оглавление не обновляется, происходит масса малоприятных вещей, и в конце концов возвращается AL=0ffH.


DOS Fn 11H: Найти 1-й совпадающий файл через FCB

  • AH = 11H
  • DS:DX = адрес неоткрытого FCB (имя файла может содержать '?')

Выход

  • AL = 0 если подходящее имя найдено (и DTA заполнена)

Описание:

В текущем оглавлении DOS ищется имя файла, соответствующее шаблону, заданному в FCB по адресу DS:DX. при неудаче возвращается AL=0ffH. если имя найдено, AL очищается, в 1-й байт DTA помещается номер дисковода (A=1, B=2, и т.д.), а в следующие 32 байта помещается элемент оглавления для найденного файла.

можно использовать при вызове расширенный FCB, чтобы выбирать файлы с указанными атрибутами. В этом случае в DTA помещаются байт 0ffH, 7 байт нулей, номер диска и элемент оглавления. В любом случае должен быть предоставлен корректный неоткрытый FCB. функция 12H Find Next FCB используется для поиска следующих имен.

Замечания:

если вы намереваетесь искать последующие файлы, не выполняйте никаких операций в/в с найденным файлом. Скопируйте FCB куда-нибудь в другое место, прежде чем открывать его. функция DOS 2.0+ 4eh "Найти 1-й файл" легче в использовании; она поддерживает обычный формат d:\путь\имяфайла.


DOS Fn 12H: Найти следующий совпадающий файл через FCB

  • AH = 12H
  • DS:DX = адрес неоткрытого FCB (имя файла может содержать '?')

Выход

  • AL = 0 если подходящее имя файла найдено (и DTA заполнена)

Описание:

используется после вызова 11H "Найти 1-й FCB" с обобщенным именем файла. каждый последующий вызов заполняет DTA очередным подходящим элементом оглавления и возвращает AL=00H. если подходящих имен больше нет, возвращается AL=0ffH. резервируемая область в FCB сохраняет информацию, необходимую для продолжения поиска. Поэтому не открывайте FCB между вызовами.


DOS Fn 13H: Удалить файл через FCB

  • AH = 13H
  • DS:DX = адрес неоткрытого FCB (имя файла может содержать '?')

Выход

  • AL = 0 если файл удален

Описание:

Эта функция удаляет все подходящие файлы в текущем оглавлении указанного диска согласно спецификации в FCB. если подходящих файлов не найдено, или если доступ отвергнут (как при попытке удалить файл с атрибутом Read-Only), функция возвращает в регистре AL значение 0ffH.


DOS Fn 14H: читать последовательный файл через FCB

  • AH = 14H
  • DS:DX = адрес открытого FCB

Выход

  • AL = 0 если чтение было успешным и DTA содержит данные
  • AL = 1 если достигнут конец файла (EOF) и данные не были считаны
  • AL = 2 если DTA+ FCB RecSiz выходит за сегмент (чтения не было)
  • AL = 3 если EOF и считана усеченная запись (дополнена нулями)

Описание:

Читает FCB RecSize байт с адреса в файле, специфицированного полями CurBlk и CurRec, в DTA. затем соответственно увеличивает значения этих полей в FCB.

перед началом последовательной обработки файла сбрасывайте CurRec в 0, так как функция 0fH Open FCB не инициализирует это поле.


DOS Fn 15H: писать последовательный файл через FCB

  • AH = 15H
  • DS:DX = адрес открытого FCB

Выход

  • AL = 0 если запись была успешной
  • AL = 1 если ошибка переполнения диска (данные не записаны)
  • AL = 2 если DTA+ FCB RecSize выходит за сегмент (записи не было)

Описание:

Пишет FCB RecSize байт из DTA в файл по адресу, специфицированному полями CurBlk и CurRec. затем соответственно увеличивает значения этих полей в FCB.

перед началом последовательной обработки файла сбрасывайте значение CurRec в 0, ибо функция 0fH Open FCB не инициализирует это поле.

Замечание:

DOS буферизует данные, записывая полный сектор за один раз.


DOS Fn 16H: создать файл через FCB

  • AH = 16H
  • DS:DX = адрес неоткрытого FCB

Выход

  • AL = 0 если файл создан без ошибок (и FCB заполнен)

Описание:

файл, специфицированный неоткрытым FCB, создается в текущем оглавлении на диске, указанном в FCB (0=текущий, 1=A, и т.д.). FCB заполняется аналогично функции 0fH Open FCB. если файл существует в момент вызова, его элемент оглавления используется для создаваемого файла, а длина файла сбрасывается в 0.

Замечание:

Handle-ориентированные функции DOS 2.0+ гораздо удобнее в работе.


DOS Fn 17H: Переименовать файл через FCB

  • AH = 17H
  • DS:DX = адрес FCB специального формата

Выход

  • AL = 0 если файл переименован успешно

Описание:

Переименовывает файл в текущем умалчиваемом оглавлении. используйте следующую структуру FCB для этой функции:

каждое из имен может содержать обобщенные символы "?":

В старом имени обобщенные символы приводят к поиску и переименованию всех подходящих файлов в текущем оглавлении.

В новом имени символ "?" означает, что в этой позиции следует оставить тот же символ, что в аналогичной позиции старого имени.

Замечание:

Эта функция позволяет переименовать само оглавление, используя расширенный FCB с подходящим атрибутом для "старого имени".


DOS Fn 19H: дать текущий диск DOS

  • AH = 19H

Выход

  • AL = номер текущего умалчиваемого диска (0=A, 1=B, и т.д.)

Описание:

возвращает номер дисковода текущего умалчивемого диска DOS.


DOS Fn 1aH: установить адрес DTA

  • AH = 1aH
  • DS:DX = адрес для DTA

Выход

  • нет =

Описание:

устанавливает адрес DTA.

  • все FCB-ориентированные операции работают с DTA.
  • DOS не позволяет операциям в/в пересекать границу сегмента.
  • функции поиска: 11H 12H 4eH и 4fH помещают данные в DTA.
  • DTA глобальна, поэтому будьте осторожны, назначая ее в рекурсивной или реентерабельной процедуре.
  • при запуске программы ее DTA устанавливается по смещению 80H относительно PSP.


DOS Fn 1bH: дать информацию FAT (текущий диск)

  • AH = 1bH

Выход

  • DS:BX = адрес байта FAT ID (отражающего тип диска)
  • DX = всего кластеров (единиц распределения) на диске
  • AL = секторов на кластер
  • CX = байт на сектор

Описание:

возвращает информацию о размере и типе умалчиваемого диска. размер диска в байтах = (DX * AL * CX). Ищите свободную память функциями 36h Disk Free или 32h Disk Info.

Версии:

DOS 1.x держит FAT в памяти и возвращает DS:BX => FAT. DOS 2.0+ может держать в памяти лишь порцию всей FAT.

Предупреждение:

Эта функция изменяет содержимое регистра DS.


DOS Fn 1cH: дать информацию FAT (любой диск)

  • AH = 1cH
  • DL = номер диска (0=текущий, 1=A, и т.д.)

Выход

  • DS:BX = адрес байта FAT ID (отражающего тип диска)
  • DX = всего кластеров (единиц распределения) на диске
  • AL = секторов на кластер
  • CX = байт на сектор

Описание:

Аналогична функции 1bH Get FAT Cur, с той разницей, что регистр DL указывает диск, для которого вы хотите получить информацию.

Версии:

Недоступна для DOS 1.x.


DOS Fn 21H: читать произвольную запись файла

  • AH = 21H
  • DS:DX = адрес открытого FCB

Выход

  • AL = 0 если чтение было успешным и DTA заполнена данными
  • AL = 1 если достигнут конец файла (EOF) и чтения не было
  • AL = 2 если DTA + FCB RecSize выходит за сегмент (чтения нет)
  • AL = 3 встречен EOF и считана усеченная запись (дополнена нулями)

Описание:

приводит поля FCB CurBlk и CurRec в соответствие с RandomRec, затем читает RecSize байт по указанному адресу в файле, помещая считанные данные в DTA.

Поле RecSize в момент вызова должно содержать длину записи, а поле RandomRec в FCB - номер требуемой записи.


DOS Fn 22H: писать произвольную запись файла

  • AH = 22H
  • DS:DX = адрес открытого FCB

Выход

  • AL = 0 если запись была успешной
  • AL = 1 при переполнении диска

· AL = 2 если DTA + FCB RecSize выходит за сегмент (нет записи)

Описание:

приводит поля FCB CurBlk и CurRec в соответствие с RandomRec, затем пишет RecSize байт из DTA на диск по указанному адресу в файле. В момент вызова поле RecSiz должно содержать длину записи, а поле RandomRec в FCB - номер требуемой записи.


DOS Fn 23H: дать размер файла через FCB

  • AH = 23H
  • DS:DX = адрес неоткрытого FCB

Выход

  • AL = 0 если файл найден

Описание:

устанавливает поле RandomRec в FCB равным числу записей размера RecSize байт, содержащихся в файле. значение RecSize должно быть задано в момент вызова. при RecSize, равном 1, RandomRec возвращает 4-байтовый размер файла в байтах. Вам может оказаться проще определить размер файла через функцию 3dH Open Handle с последующей 42H Lseek Handle (при AL=2).


DOS Fn 24H: установить адрес произвольной записи в файле

  • AH = 24H
  • DS:DX = адрес открытого FCB

Выход

  • нет =

Описание:

устанавливает поле RandomRec в FCB на файловый адрес, соответствующий значениям полей CurBlk и CurRec.


DOS Fn 25H: установить вектор прерывания

  • AH = 25H
  • AL = номер прерывания
  • DS:DX = вектор прерывания: адрес программы обработки прерывания

Выход

  • нет =

Описание:

устанавливает значение элемента таблицы векторов прерываний для прерывания с номером AL равным DS:DX. это равносильно записи 4-байтового адреса в 0000:(AL*4), но, в отличие от прямой записи, DOS здесь знает, что вы делаете, и гарантирует, что в момент записи прерывания будут заблокированы.

Предупреждение:

Не забудьте восстановить DS (если необходимо) после этого вызова.


DOS Fn 26H: Построить PSP

  • AH = 26H
  • DX = адрес сегмента (параграфа) для нового PSP
  • CS = сегмент PSP, используемого как шаблон для нового PSP

Выход

  • нет =

Описание:

устанавливает PSP для порождаемого процесса по адресу DX:0000.

  • текущий PSP (100H байт, начиная с CS:0), копируется в DX:0
  • поле MemTop соответственно корректируется
  • векторы Terminate, Ctrl-Break и Critical Error копируются в PSP из векторов прерываний INT 22H, INT 23H и INT 24H после этого вы можете загрузить программу с диска и передать ей управление посредством FAR JMP.

Замечание:

если вы перехватываете INT 21H, позаботьтесь о помещении в стек корректного CS:IP. Еще лучше использовать функцию 4cH (EXEC).


DOS Fn 27H: читать произвольный блок файла

  • AH = 27H
  • DS:DX = адрес открытого FCB
  • CX = число считываемых записей

Выход

  • AL = 0 если чтение успешно и DTA заполнена данными
  • AL = 1 если достигнут конец файла (EOF) и данные не считаны
  • AL = 2 если DTA + FCB (RecSize * CX) выходит за границу сегмента
  • AL = 3 если EOF и считана усеченная порция (дополнена нулями)
  • CX = действительное число считанных записей

Описание:

Читает несколько записей из файла, начиная с файлового адреса, специфицированного полем RandomRec в FCB. Помещает данные в память, начиная с адреса DTA. число считанных байт = FCB RecSize*CX. Поля RandomRec, CurBlk и CurRec корректируются, чтобы указывать на следующую запись (первую запись за прочитанными).


DOS Fn 28H: писать произвольный блок файла

  • AH = 28H
  • DS:DX = адрес открытого FCB
  • CX = число записываемых записей (если CX=0, уст. размер файла)

Выход

  • AL = 0 если запись успешна
  • AL = 1 при переполнении диска
  • AL = 2 если DTA + FCB (RecSize * CX) выходит за границу сегмента
  • CX = действительное число записанных записей

Описание:

записывает несколько записей в файл, начиная с файлового адреса, специфицированного полем RandomRec в FCB. данные берутся из памяти, начиная с адреса DTA. число записываемых байт=(RecSize * CX). если CX=0 при вызове, то размер файла усекается или расширяется до величины RandomRec * RecSize (никакие данные не записываются).


DOS Fn 29H: Разобрать имя файла

  • AH = 29H
  • DS:SI = адрес исходной текстовой строки для разбора
  • ES:DI = адрес буфера для результирующего неоткрытого FCB
  • AL = битовые флаги, указывающие опции разбора (см. ниже)

Выход

  • AL = 0 если результирующий FCB не содержит обобщенных символов
  • AL = 1 если результирующий FCB содержит обобщенные символы
  • AL = 0ffH если неверно обозначение диска в имени файла
  • DS:SI = изменен: указывает на символ сразу вслед за именем файла
  • ES:DI = не изменен: указывает на неоткрытый FCB

Описание:

создает неоткрытый FCB из строки текста или параметра команды. текст, начиная с DS:SI, анализируется как имя файла в формате D:FILENAME.EXT, и буфер по адресу ES:DI заполняется как соответственно форматированный FCB.

Эта функция НЕПРИМЕНИМА, если текстовая строка содержит путь. обычно она используется для перевода в верхний регистр и удаления точки из имени файла, введенного с клавиатуры. при этом '*' переводится в ряд '?'. Эта функция позволяет предусмотреть умолчание в целевом FCB (например, заранее заполнить расширение = "WKS").

Способ разбора определяется битовыми флагами в AL:


DOS Fn 2aH: дать системную дату

  • AH = 2aH

Выход

  • AL = день недели (0=Вск, 1=Пнд,...6=Суб) DOS 3.0+
  • CX = год (1980 до 2099)
  • DH = месяц (1 до 12)
  • DL = день (1 до 31)

Описание:

возвращает текущую дату, как она известна системе.

Версии:

DOS 2.x не гарантирует возврата в AL значения дня; все версии 1.0+ возвращают правильный день недели. версии до 2.1 имеют проблемы с переходом даты.


DOS Fn 2bH: установить системную дату

  • AH = 2bH
  • CX = год (1980 до 2099)
  • DH = месяц (1 до 12)
  • DL = день (1 до 31)

Выход

  • AL = 0 если дата корректна

Описание:

устанавливает системную дату DOS.


DOS Fn 2cH: дать время DOS

  • AH = 2cH

Выход

  • CH = часы (0 до 23)
  • CL = минуты (0 до 59)
  • DH = секунды (0 до 59)
  • DL = сотые доли секунды (0 до 99)

Описание:

возвращает текущее время, как оно известно системе.

Замечание:

Поскольку системные часы имеют частоту 18.2 тиков в секунду (интервал 55мс), DL имеет точность 0.04 сек.


DOS Fn 2dH: установить время DOS

  • AH = 2dH
  • CH = часы (0 до 23)
  • CL = минуты (0 до 59)
  • DH = секунды (0 до 59)
  • DL = сотые доли секунды (0 до 99)

Выход

  • AL = 0 если время корректно

Описание:

устанавливает системное время DOS.


DOS Fn 2eH: установить/сбросить переключатель верификации

  • AH = 2eH
  • AL = 0 отключить верификацию
  • = 1 включить верификацию

Выход

  • нет =

Описание:

устанавливает, должна ли DOS верифицировать (считывать обратно) каждый сектор, записываемый на диск. это замедляет операции записи на диск, но гарантирует максимальную надежность записи. функция 56H Get Verify возвращает текущий статус верификации DOS.


DOS Fn 2fH: дать адрес текущей DTA

  • AH = 2fH

Выход

  • ES:BX = адрес начала текущей DTA

Описание:

возвращает адрес начала области ввода-вывода (DTA). Поскольку DTA глобальна для всех процессов, в рекурсивной процедуре (например, при проходе по дереву оглавления) может потребоваться сохранить адрес DTA, а впоследствии восстановить его посредством функции 1aH "Уст. DTA".

Замечание:

Эта функция изменяет сегментный регистр ES.


DOS Fn 30H: дать номер версии DOS

  • AH = 30H

Выход

  • AL = старший номер версии
  • AH = младший номер версии
  • BX,CX = 0000H DOS 3.0+

Описание:

возвращает в AX значение текущего номера версии DOS. например, для DOS 3.2, в AL возвращается 3, в AH - 2.

Замечание:

если в AL возвращается 0, можно предполагать, что работает DOS более ранней версии, чем DOS 2.0.

Версии:

DOS 2.x не гарантирует очистки регистров CX и BX.


DOS Fn 31H: завершиться и остаться резидентным - KEEP

  • AH = 31H
  • AL = код выхода
  • DX = объем памяти, оставляемой резидентной, в параграфах

Выход

  • нет = (неприменим)

Описание:

выходит в родительский процесс, сохраняя код выхода в AL. код выхода можно получить через функцию 4dH Wait. DOS устанавливает начальное распределение памяти, как специфицировано в DX, и возвращает управление родительскому процессу, оставляя указанную память резидентной (число байт = DX * 16). Эта функция перекрывает функцию INT 27H, которая не возвращает код выхода и неспособна установить резидентную программу, большую 64K.


DOS Fn 32H: дать информацию DOS о диске

  • AH = 32H НЕТ В ДОКУМЕНТАЦИИ
  • DL = номер диска (0=текущий, 1=A, и т.д.)

Выход

  • AL = 0 если DL задавал корректный диск
  • FF = 0ffH если диск задан неверно
  • DS:BX = адрес блока информации диска для запрошенного устройства

Описание:

возвращает блок информации, представляющей интерес для приложений и утилит, выполняющих доступ к диску, поддерживаемый драйверами устройств, на уровне секторов. некоторые дисководы (особенно незагружаемые) функционируют исключительно через свои драйверы устройств. такие диски могут содержать неверную информацию в корневой записи и таблице разделов, что делает очень трудным определение, например, размера корневого оглавления, числа таблиц FAT, и т.п. блок информации диска содержит все данные такого рода в хорошо форматированной структуре. это может быть единственным способом определить адрес драйвера устройства.

Предупреждение:

изменяет сегментный регистр DS. Эта недокументированная функция может измениться в будущих версиях.


DOS Fn 33H: установить/опросить статус Ctrl-Break

  • AH = 33H
  • AL = 0 чтобы опросить текущий статус контроля Ctrl-Break
  • AL = 1 чтобы установить статус контроля Ctrl-Break
  • DL = требуемый статус (0=OFF, 1=ON) (только при AL=1)

Выход

  • DL = текущий статус (0=OFF, 1=ON)

Описание:

если AL=0, в DL возвращается текущий статус контроля Ctrl-Break. если AL=1, в DL возвращается новый текущий статус. когда статус ON, DOS проверяет на Ctrl-Break с консоли для большинства функций (исключая 06H и 07H). при обнаружении, выполняется INT 23H (если оно не перехватывется, то это снимает процесс). когда статус OFF, DOS проверяет на Ctrl-Break лишь при операциях стандартного в/в, стандартной печати и стандартных операциях AUX.


DOS Fn 34H: адрес статуса реентерабельности DOS

  • AH = 34H НЕТ В ДОКУМЕНТАЦИИ

Выход

  • ES:BX = адрес флага активности DOS

Описание:

Эту недокументированную функцию использует PRINT (фоновый процессор печатного спулинга) в момент его установки, так что он может позднее определить, можно ли использовать файловые функции DOS.

При возврате из этой функции ES:BX содержит адрес внутреннего флага DOS, указывающего, выполняется ли в данный момент какая-либо функция DOS. когда спулеру PRINT требуется открыть файл (или использовать какую-либо функцию DOS), он проверяет этот флаг. если ES:[BX] содержит не 0, фоновая программа (TSR, либо popup) НЕ ДОЛЖНА использовать никаких функций DOS.

Резидентные popup-программы часто активизируются по прерыванию от таймера или клавиатуры. так как это может произойти в любой момент, не исключено, что в этот момент будет выполняться какая-либо функция DOS. если теперь popup вызовет функцию DOS, это разрушит стек DOS и, вероятно, приведет к катастрофической ошибке. Путем проверки этого флага popup может определить, возможны ли вызовы функций DOS.

Это, однако, осложняется тем фактом, что COMMAND.COM и некоторые другие программы проводят большую часть времени, запросив ввод с клавиатуры через функцию 0aH (дать строку). таким образом, флаг почти всегда взведен, и на службу DOS наложено табу.

Вы можете выйти из положения, перехватывая INT 21H и отслеживая вызовы функции 0aH. когда приходит такой запрос, не выполняйте его немедленно. Вместо этого организуйте цикл, в котором с некоторой задержкой вызывайте функцию 0bH (дать статус ввода). Циклите, пока не заметите, что нажата клавиша. после этого можно выйти из цикла и вызвать функцию 0aH. Понятно, что при таком способе всегда существует окно времени, в котором проснувшийся popup может без боязни использовать функции DOS. можно также перехватывать INT 28H, если вы любите рисковать.

Предупреждение:

Эта функция не документирована, и опираться на нее рискованно. большинство popup-программ перехватывают INT 21H и отслеживают статус DOS индивидуально (ибо им и так приходится отслеживать 0aH).


DOS Fn 35H: дать вектор прерывания

  • AH = 35H
  • AL = номер прерывания (00H до 0ffH)

Выход

  • ES:BX = адрес обработчика прерывания

Описание:

возвращает значение вектора прерывания для INT (AL); то есть, загружает в BX 0000:[AL*4], а в ES - 0000:[(AL*4)+2].

Предупреждение:

Эта функция изменяет сегментный регистр ES.


DOS Fn 36H: дать свободную память диска

  • AH = 36H
  • DL = номер диска (0=текущий, 1=A, и т.д.)

Выход

  • AX = 0ffffH, если AL содержал неверный номер диска или число секторов на кластер, если нет ошибок.
  • BX = доступных кластеров.
  • CX = байт на сектор.
  • DX = всего кластеров на диске.

Описание:

возвращает данные для подсчета общей и доступной дисковой памяти. если в AX возвращено 0ffffH, значит, вы задали неверный диск. Иначе, свободная память в байтах = (AX * BX * CX) всего памяти в байтах = (AX * CX * DX)


DOS Fn 37H: установить/опросить символ-переключатель

  • AH = 37H НЕТ В ДОКУМЕНТАЦИИ
  • AL = 0 чтобы опросить текущий переключатель
  • = 1 чтобы установить символ-переключатель
  • DL = символ-переключатель (при AL=1)

Выход

  • DL = текущий символ-переключатель DOS

Описание:

устанавливает или опрашивает глобальный переключатель DOS. переключатель (SWITCHAR) - это символ, используемый в командной строке как разделитель опций. умолчание - '/' (например, DIR /w/p), но вы можете изменить SWITCHAR на '-' (напр., DIR -w-p), если хотите, чтобы ваша система производила впечатление системы UNIX. Общепринято опрашивать значение SWITCHAR перед разбором области неформатированных параметров в PSP для выделения опций команды.

Предупреждение:

Эта недокументированная команда может измениться в будущих версиях DOS. Рекомендуется НЕ изменять SWITCHAR, поскольку многие программы не опрашивают его значение при разборе командной строки.


DOS Fn 38H: дать/установить информацию о стране

  • AH = 38H
  • DX = 0ffffH чтобы установить код страны равным AL (или BX)
  • DS:DX = адрес локального буфера для чтения блокa данных страны
  • AL = 0 чтобы получить данные для текущей страны
  • = 1 до 0feH чтобы получить данные для указанной страны < 255
  • = 0ffH чтобы получить данные для кода страны ‡ 255
  • BX = (если AL=0ffH) 16-битовый код страны

Выход

  • AX = код ошибки если флаг CF установлен
  • BX = код страны (если AL=0 при входе)

Описание:

если DX=0ffffH, то текущий код страны (см. ниже) устанавливается равным AL (если AL=0ffH, то код страны устанавливается равным BX). обычно код страны устанавливается в файле CONFIG.SYS. если DX < 0ffffH, то DS:DX адресует буфер пользователя, в который помещается 20-байтовый блок данных страны для указанной страны.

Замечание:

адрес вызова CaseMap можно использовать для определения сопоставляющей (сортирующей) последовательности символов в разных алфавитах.

Версии:

DOS 2.x не позволяет устанавливать код страны. В этом случае параметры вызова проще:

Вход

  • AL=0
  • DS:DX = адрес 20-байтового локального буфера

Выход

  • Пересылает в DS:DX блок данных страны для DOS 2.x

  Hex  Dec  страна          Keybrd  дата      время         формат валюты  DS

  3dH  061  Австралия               DD-MM-YY  13:00:00       $1,000.00      ,
  20H  032  Бельгия                 DD/MM/YY  13:00:00        1 000,00 F    ;
   2   002  Французская Канада      YY-MM-DD  13:00:00        1 000,00 $    ;
  2dH  045  Дания                   DD/MM/YY  13.00:00        1.000,00 DKR  ;
 166H  358  Финляндия               DD-MM-YY  13:00:00        1 000,00 MK   ;
  21H  033  Франция         keybFR  DD/MM/YY  13:00:00        1 000,00 F    ;
  31H  049  Германия        keybGR  DD.MM.YY  13.00.00      DM1.000,00      ;
  27H  039  Италия          keybIT  DD/MM/YY  13:00:00        1.000,Lit.    ;
 3ccH  972  Израиль                 DD/MM/YY  13:00:00      Щ 1,000.00      ,
 311H  785  Средний Восток          DD/MM/YY  01:00:00 PM     1.000,000 $   ;
  1fH  031  Нидерланды              DD-MM-YY  13:00:00       Я1.000,00      ;
  2fH  047  Норвегия                DD/MM/YY  13.00.00     KR 1.000,00      ;
 15fH  351  португалия              DD/MM/YY  13:00:00        1.000$00      ;
  22H  034  Испания         keybSP  DD/MM/YY  13:00:00        1.000,00 Ю    ;
  2eH  046  Швеция                  YY-MM-DD  13.00.00    SEK 1.000,00      ;
  29H  041  Швейцария               DD.MM.YY  13.00.00     Fr 1,000.00      ,
  2cH  044  Великобритания  keybUK  DD-MM-YY  13:00:00       Ь1,000.00      ,
   1   001  Соединенные Штаты       MM-DD-YY  01:00:00 PM    $1,000.00      ,


DOS Fn 39H: создать новое оглавление -- MKDIR

  • AH = 39H
  • DS:DX = адрес строки ASCIIZ с именем оглавления

Выход

  • AX = код ошибки если CF установлен

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяоглавл",0 если диск и/или корневой путь опущены, то принимаются по умолчанию. Подоглавление создается и связывается с существующим деревом. если флаг CF установлен при возврате, то AX содержит код ошибки, и оглавление не создается.


DOS Fn 3aH: Удалить оглавление -- RMDIR

  • AH = 3aH
  • DS:DX = адрес строки ASCIIZ с именем оглавления

Выход

  • AX = код ошибки если CF установлен

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяоглавл",0. если диск и/или корневой путь опущены, то принимаются по умолчанию. Подоглавление удаляется из структуры оглавления. если флаг CF установлен при возврате, то AX содержит код ошибки, и оглавление не удаляется.

Замечание:

оглавление не должно содержать файлов и подоглавлений и не должно быть связано возможными ограничениями DOS (например, не должно быть задействовано в активных командах JOIN или SUBST).


DOS Fn 3bH: установить умалчиваемое оглавление DOS -- CHDIR

  • AH = 3bH
  • DS:DX = адрес строки ASCIIZ с именем оглавления

Выход

  • AX = код ошибки если CF установлен

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяоглавл",0. если диск и/или корневой путь опущены, то принимаются по умолчанию. указанное подоглавление для указанного диска становится текущим (умалчиваемым) оглавлением DOS для этого (или текущего) диска. если флаг CF установлен при возврате, то AX содержит код ошибки, и текущее оглавление для выбранного диска не изменяется.


DOS Fn 3cH: создать файл через описатель

  • AH = 3cH
  • DS:DX = адрес строки ASCIIZ с именем файла
  • CX = атрибут файла

Выход

  • AX = код ошибки если CF установлен и описатель файла если ошибки нет

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяфайла",0. если диск и/или путь опущены, они принимаются по умолчанию.

  • файл создается в указанном (или умалчиваемом) оглавлении
  • файл открывается в режиме доступа чтение/запись
  • вы должны созранить описатель (handle) для последующих операций
  • если файл уже существует:
  • при открытии файл усекается до нулевой длины
  • если атрибут файла - только чтение, открытие отвергается (атрибут можно изменить функцией 43H изменить атрибут)
  • CONFIG.SYS специфицирует число доступных описателей в системе
  • используйте функцию 5bH создать Новый файл, если вы не хотите перекрывать (усекать) существующий файл.

Оставить комментарий

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.

| Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог


DOS Fn 3dH: открыть описатель файла

  • AH = 3dH
  • DS:DX = адрес строки ASCIIZ с именем файла
  • AL = режим открытия

Выход

  • AX = код ошибки если CF установлен и описатель файла если нет ошибки.

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяфайла",0. Если диск и/или путь опущены, они принимаются по умолчанию.

  • файл должен существовать. См. функцию 3cH (создать файл).
  • файл открывается в выбранном режиме доступа / режиме открытия для совместимости с DOS 2.x и избежания сетевых режимов, задавайте:
    • AL = 0 чтобы открыть для чтения
    • AL = 1 чтобы открыть для записи
    • AL = 2 чтобы открыть для чтения и записи
  • указатель чтения/записи устанавливается в 0. См. 42H (LSEEK)
  • вы должны сохранить описатель (handle) для последующих операций
  • разделение файлов должно быть активизировано (команда DOS SHARE), если запрашивается открытие в одном из режимов разделения.
  • CONFIG.SYS специфицирует число доступных описателей файлов.


DOS Fn 3eH: Закрыть описатель файла

  • AH = 3eH
  • BX = описатель файла

Выход

  • AX = код ошибки если CF установлен

Описание:

BX содержит описатель файла (handle), возвращенный при открытии. файл, представленный этим описателем, закрывается, его буфера сбрасываются, и оглавление обновляется корректными размером, временем и датой.

Из-за нехватки описателей файлов (максимум 20, по умолчанию 8), вам может понадобиться закрыть часть умалчиваемых описателей, как, например, описатель 3 (стандартный AUX).


DOS Fn 3fH: читать файл через описатель

  • AH = 3fH
  • BX = описатель файла
  • DS:DX = адрес буфера для чтения данных
  • CX = число считываемых байт

Выход

  • AX = код ошибки если CF установлен или число действительно прочитанных байт

Описание:

CX байт данных считываются из файла или устройства с описателем, указанным в BX. данные читаются с текущей позиции указателя чтения/записи файла и помещаются в буфер вызывающей программы, адресуемый через DS:DX.

Используйте функцию 42H LSEEK, чтобы установить указатель файла, если необходимо (OPEN сбрасывает указатель в 0). Модифицирует указатель чтения/записи файла, подготавливая его к последующим операциям чтения или записи.

Вы должны всегда сравнивать возвращаемое значение AX (число прочитанных байт) с CX (запрошенное число байт):

  • если AX = CX, (и CF сброшен) - чтение было корректным без ошибок
  • если AX = 0, достигнут конец файла (EOF)
  • если AX < CX (но ненулевой):
    • при чтении с устройства - входная строка имеет длину AX байт
    • при чтении из файла - в процессе чтения достигнут EOF

Замечания:

Эта функция превосходит сложные и неудобные FCB-функции. Она эффективно сочетает произвольный и последовательный доступ, позволяя пользователю выполнять свое собственное блокирование. Удобно использовать эту функцию для чтения стандартных описателей, таких как описатели стандартного в/в, взамен многочисленных буферизующих и посимвольных FCB-функций ввода. Когда вы читаете с устройства, AX возвращает длину считанной строки с учетом завершающего возврата каретки CR (ASCII 0dH).


DOS Fn 40H: писать в файл через описатель

  • AH = 40H
  • BX = описатель файла
  • DS:DX = адрес буфера, содержащего записываемые данные
  • CX = число записываемых байт

Выход

  • AX = код ошибки если CF установлен
  • AL = число реально считанных байт (лучший тест для ошибок)

Описание:

CX байт данных записывается в файл или на устройство с описателем, заданным в BX. данные берутся из буфера, адресуемого через DS:DX. данные записываются, начиная с текущей позиции указателя чтения/записи файла.

Используйте функцию 42H LSEEK, чтобы установить указатель файла, если необходимо (OPEN сбрасывает указатель в 0). Обновляет указатель чтения/записи файла, чтобы подготовиться к последующим операциям последовательного чтения или записи.

Вы должны всегда сравнивать возвращаемое значение AX (число записанных байт) с CX (запрошенное число байт для записи).

  • если AX = CX, запись была успешной
  • если AX < CX, встретилась ошибка (скорее всего, переполнение)

Замечание:

Эта функция превосходит сложные и неудобные FCB-функции. Она эффективно сочетает произвольный и последовательный доступ, позволяя пользователю осуществлять собственное блокирование. Удобно использовать эту функцию для вывода на умалчиваемые устройства, такие как стандартный вывод, взамен использования различных функций вывода текста.


DOS Fn 41H: Удалить файл

  • AH = 41H
  • DS:DX = адрес строки ASCIIZ с именем файла

Выход

  • AX = код ошибки если CF установлен

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяфайла",0. Если диск и/или путь опущены, они принимаются по умолчанию. имя файла не может содержать обобщенные символы ('?' и '*'). файл удаляется из заданного оглавления заданного диска. если файл имеет атрибут только чтение, то перед удалением необходимо изменить этот атрибут через функцию 43H CHMOD.


DOS Fn 42H: установить указатель файла -- LSEEK

  • AH = 42H
  • BX = описатель файла
  • CX:DX = на сколько передвинуть указатель: (CX * 65536) + DX
  • AL = 0 переместить к началу файла + CX:DX
  • AL = 1 переместить к текущей позиции + CX:DX
  • AL = 2 переместить к концу файла + CX:DX

Выход

  • AX = код ошибки если CF установлен
  • DX:AX = новая позиция указателя файла (если нет ошибки)

Описание:

перемещает логический указатель чтения/записи к нужному адресу. Очередная операция чтения или записи начнется с этого адреса.

Замечение:

Вызов с AL=2, CX=0, DX=0 возвращает длину файла в DX:AX. DX здесь старшее значащее слово: действительная длина (DX * 65536) + AX.


DOS Fn 43H: установить/опросить атрибут файла -- CHMOD

  • AH = 43H
  • DS:DX = адрес строки ASCIIZ с именем файла
  • AL = код подфункции: 0 = извлечь текущий атрибут файла
  • AL = 1 = установить атрибут файла
  • CX = новый атрибут файла (для подфункции 01H)

Выход

  • AX = код ошибки если CF установлен
  • CX = текущий атрибут файла (для подфункции 00H)

Описание:

DS:DX указывает на строку ASCIIZ в формате: "d:\путь\имяфайла",0. Если диск и/или путь опущены, они принимаются по умолчанию. атрибут файла извлекается или устанавливается, согласно коду в AL.

Замечание:

чтобы спрятать оглавление, используйте CX=02H (а не 12H, как вы, возможно, ожидали).


DOS Fn 44H: управление устройством в/в -- IOCTL

  • AH = 43H
  • AL = код подфункции:
  • AL = 00H - дать информацию устр-ва
  • AL = 01H - уст. информацию устр-ва
  • AL = 02H - читать с симв. устр-ва
  • AL = 03H - писать на симв. устр-во
  • AL = 04H - читать с блочного устр.
  • AL = 05H - писать на блочное устр.
  • AL = 06H - дать статус ввода
  • AL = 07H - дать статус вывода
  • AL = 08H - запрос съемн носителя
  • AL = 09H - запрос лок/удал устр-ва
  • AL = 0aH - запрос лок/удал описателя
  • AL = 0bH - счет повторов разделения
  • AL = 0cH - (зарезервировано)
  • AL = 0dH - общий IOCTL [DOS 3.2+]
  • AL = 0eH - дать логич устр-во [DOS 3.2+]
  • AL = 0fH - уст логич устр-во [DOS 3.2+]
  • прочие = (в зависимости от подфункции)

Выход

  • AX = код ошибки если CF установлен или иное значение (в зависимости от подфункции)

Описание:

IOCTL предоставляет метод взаимодействия с устройствами и получения информации о файлах. входные параметры и выходные значения варьируются в зависимости от кода подфункции в регистре AL.

Версии:

  • подфункции 0-7 ............ DOS 2.1+
  • подфункции 8,0bH .......... DOS 3.0+
  • подфункции 9,0aH .......... DOS 3.1+
  • подфункции 0dH,0eH,0fH .... DOS 3.2+

· Подфукция 00H: Запросить флаги информации об устройстве

· вход: BX= описатель файла (устройство или дисковый файл)

· выход: DX= IOCTL Инф об устр

· Подфукция 01H: установить флаги информации об устройстве

· вход:

  • BX = описатель файла (устройство или дисковый файл)
  • DX = IOCTL Инф об устр (DH должен быть нулевым)

· выход: DX= IOCTL Инф об устр

· Подфукция 02-03: читать (AL=02H) или писать (AL=03H) строку IOCTL на СИМВОЛЬНОЕ устр

· вход:

  • DS:DX = адрес буфера (чтение) или данных (запись)
  • CX= число передаваемых байт
  • BX= описатель файла (только устройство -- не файл!)

· выход: AX= код ошибки если CF установлен

· Подфукция 04-05: читать (AL=04H) или писать (AL=05H) строку IOCTL на БЛОЧНОЕ устр

· вход:

  • DS:DX = адрес буфера (чтение) или данных (запись)
  • CX = число передаваемых байт
  • BL = ID диска (0=текущий, 1=A, и т.д.)

· выход:

  • AX = код ошибки если CF установлен
  • AX =действительное число переданных байт (если CF=NC=0)

· Подфукция 06-07: дать статус ввода (AL=06H) или статус вывода (AL=07H)

· вход: BX= описатель файла (устройство или дисковый файл)

· выход:

  • AL= 0ffH=не конец файла; 0=EOF (для дисковых описателей)
  • AL= 0ffH=готово; 0=не готово (для устройств)

· Подфукция 08H: использует ли блочное устройство съемный носитель? [DOS 3.0+]

· вход: BL= ID диска (0=текущий, 1=A, и т.д.)

· выход:

  • AX = 00H - съемный носитель (т.е. флоппи-диск)
  • AX = 01H - не съемный (твердый диск или RAM-диск)
  • AX = 0fH - код ошибки если BL содержит неверный диск

· Подфукция 09H: Является ли устройство съемным в сети? [DOS 3.1+]

· вход: BL = ID диска (0=текущий, 1=A, и т.д.)

· выход: DX = атрибут устройства для диска. если бит 12=1 (т.е., DX & 1000H = 1000H), то устройство съемное.

· Подфукция 0aH: принадлежит ли описатель файла локальному или удаленному устройству в сети? [DOS 3.1+] Нам посоветовали не использовать эту подфункцию. Вместо этого трактуйте удаленные устройства как локальные.

· в ход: BX = описатель файла (только устройство -- не файл)

· выход: DX = атрибут устройства для диска. если бит 15=1 (т.е., DX & 8000H = 8000H), то устройство удаленное.

· Подфукция 0bH: контроль повтора/задержки при разделении и блокировке файлов. 3.0+

· вход:

  • DX= число попыток перед вызовом INT 24H "Критическая ошибка"
  • CX= счетчик цикла между попытками

· выход: AX= код ошибки если CF установлен

· замечание: умолчание - 3 попытки и счетчик цикла 1.

· Подфукция 0dH: Общий вызов IOCTL отрабатывает разнообразные функции управления. Начиная с DOS 3.2, можно создавать драйверы устройств, работающие на уровне дорожек (форматирование, чтение/запись). [DOS 3.2+] Код действия в регистре CL определяет "подподфункцию":

· вход:

  • CL = код действия
    • 40H = установить параметры устройства
    • 60H = дать параметры устройства
    • 41H = писать дорожку логического устройства
    • 61H = читать дорожку логического устройства
    • 42H = форматировать дорожку с верификацией
    • 62H = Верифицировать дорожку логического устройства
  • DS:DX=> адрес пакета данных IOCTL

· выход:

  • AX= код ошибки если CF установлен
  • DS:DX=> пакет данных может содержать информацию возврата.

· Подфукция 0eH: Выяснить, назначил ли драйвер устройства несколько логических устройств одному физическому устройству. [DOS 3.2+]

· вход: BL= ID диска (0=текущий, 1=A, и т.д.)

· выход: AX= код ошибки если CF установлен

  • AL = 0 если ровно одна буква диска назначена устройству BL
  • AL = (1=A, 2=B и т.д.) если назначено несколько логических устройств, AL содержит ID текущего назначенного диска

· Подфукция 0fH: Сообщить драйверу блочного устройства ID устройства для обработки. когда с физическим устройством ассоциируется несколько логических, DOS выдает сообщение "Insert diskette for drive X:...". Эта функция позволяет вам сообщать DOS, что диск с указанным ID уже установлен, тем самым обходя сообщение. [DOS 3.2+]

· вход: BL= ID диска (0=текущий, 1=A, и т.д.)

· выход:

  • AX= код ошибки если CF установлен
  • AL = 0 если ровно один ID назначен устройству BL
  • AL = (1=A, 2=B и т.д.) ID выбранного устройства, которое будет использоваться в последующих операциях в/в.

· Замечание: Эта функция должна вызываться перед любой операцией в/в на логическом устройстве. Иначе DOS может выдать сообщение.


DOS Fn 45H: Дублировать описатель файла -- DUP

  • AH = 45H
  • BX = существующий описатель файла

Выход

  • AX = новый описатель файла, дублирующий оригинал или код ошибки если CF установлен.

Описание:

Создает дополнительный описатель файла, ссылающийся на тот же поток в/в, что и существующий описатель. Любое продвижение указателя чтения/записи для одного описателя действует на его дубликат -- включая любые операции чтения, записи или перемещения указателя посредством функции 42H LSEEK. Новый описатель наследует ограничения режима открытия оригинала. Эта функция используется с одной главной целью: вы можете закрыть описатель, заставляя DOS записать файловые буфера. такой способ DUP/CLOSE - быстрее, чем закрытие и повторное открытие файла.


DOS Fn 46H: переназначить описатель -- FORCDUP

  • AH = 46H
  • BX = целевой описатель файла (должен уже существовать)
  • CX = исходный описатель файла (должен уже существовать)

Выход

  • AX = код ошибки если CF установлен

Описание:

Заставляет описатель файла (handle) ссылаться на другой файл или устройство. описатель в CX (источник) закрывается, если он открыт, а затем становится дубликатом описателя в BX (назначения). Иными словами, описатели в CX и BX будут ссылаться на один и тот же физический файл или устройство.

используется для переназначения стандартного в/в. пример:

  • Откроем файл "C:\STDOUT.TXT" через функцию 3dH Open File и получим описатель (например, 05).
  • установим BX=05, CX=01 и вызовем эту функцию. (замечание: описатель 01 - это предопределенный описатель "стандартного выходного устройства").
  • Теперь можно вызвать функцию 3eH Close File и закрыть handle 05. можно обращаться к файлу STDOUT.TXT через описатель 01.
  • Стало быть, дисковый файл "C:\STDOUT.TXT" будет отныне получать весь вывод, создаваемый всеми процессами (текущим и порожденными) через любую функцию символьного в/в DOS, так же как и любой вывод в описатель файла 01 через функцию DOS 40H.
  • когда вы выходите в COMMAND.COM, предопределенные описатели устанавливаются на обычные устройства (например, описатель 01 устанавливается на "CON").


DOS Fn 47H: дать умалчиваемое оглавление DOS

  • AH = 47H
  • DS:SI = адрес локального буфера для результирующего пути (64 байта)
  • DL = номер диска (0=текущий, 1=A, и т.д.)

Выход

  • AX = код ошибка если CF установлен

Описание:

В пользовательский буфер по адресу DS:SI помещается в форме ASCIIZ путь текущего умалчиваемого оглавления для диска, указанного в DL. Путь возвращается в формате: "путь\оглавление",0. Не подставляется впереди буква диска, а сзади не подставляется символ "\". например, если текущим является корневое оглавление, эта функция вернет вам пустую строку (DS:[SI] = 0).


DOS Fn 48H: распределить память (дать размер памяти)

  • AH = 48H
  • BX = запрошенное количество памяти в 16-байтовых параграфах

Выход

  • AX = код ошибки если CF установлен
  • BX = размер доступной памяти в параграфах (если памяти нехватает)
  • AX = сегментный адрес распределенного блока (если нет ошибок)

Описание:

распределяет блок памяти длиной BX параграфов, возвращая сегментный адрес этого блока в AX (блок начинается с AX:0000). если распределение неудачно, взводится Carry-флаг, в AX возвращается код ошибки, а BX содержит максимальный размер доступной для распределения памяти (в параграфах).

Чтобы определить наибольший доступный кусок, общепринято устанавливать BX=0ffffH перед вызовом. распределение завершится с ошибкой, возвратив размер максимального блока памяти в BX.

Замечание:

когда процесс получает управление через функцию 4bH EXEC, вся доступная память уже распределена ему.


DOS Fn 49H: Освободить распределенный блок памяти

  • AH = 49H
  • ES = сегментный адрес (параграф) освобождаемого блока памяти

Выход

  • AX = код ошибки если CF установлен

Описание:

Освобождает блок памяти, начинающийся с адреса ES:0000. этот блок становится доступным для других запросов системы. Вообще говоря, вы должны освобождать лишь те блоки памяти, которые вы получили через функцию 48H распределить память. Родитель отвечает за освобождение памяти порожденных процессов. Тем не менее, ничто не препятствует вам освобождать память чужих проыессов.


DOS Fn 4aH: Сжать или расширить блок памяти

  • AH = 4aH
  • ES = сегмент распределенного блока памяти
  • BX = желаемый размер блока в 16-байтовых параграфах

Выход

  • AX = код ошибки если CF установлен
  • BX = наибольший доступный блок (если расширение неудачно)

Описание:

Изменяет размер существующего блока памяти. Когда программа получает управление, функция 4bH EXEC уже распределила блок памяти, начиная с PSP, который содержит всю доступную память. чтобы освободить память для запуска порождаемых процессов, блок памяти, начинающийся с PSP, необходимо сначала сжать.

Замечание:

функция 31H (KEEP) и INT 27H (TSR) сжимают блок по адресу PSP.


DOS Fn 4bH: выполнить или загрузить программу -- EXEC

  • AH = 4bH
  • DS:DX = адрес строки ASCIIZ с именем файла, содержащего программу
  • ES:BX = адрес EPB (EXEC Parameter Block - блока параметров EXEC)
  • AL = 0 = загрузить и выполнить
  • AL = 3 = загрузить программный оверлей

Выход

  • AX = код ошибки если CF установлен

Описание:

предоставляет средства одной программе (родителю) вызвать другую программу (ребенка), которая по завершению возвратит управление родителю.

DS:DX указывает на строку ASCIIZ в форме: "d:\путь\имяфайла",0. если диск или путь опущены, они подразумеваются по умолчанию.

ES:BX указывает на блок памяти, подготовленный как EPB, формат которого зависит от запрошенной подфункции в AL.

AL=0 EXEC: так как родительская программа первоначально получает всю доступную память в свое распоряжение, вы должны освободить часть памяти через функцию 4aH до вызова EXEC (AL=0). обычная последовательность:

  1. Вызовите функцию 4aH с ES=сегменту PSP и BX=минимальному объему памяти, требуемой вашей программе (в параграфах).
  2. Подготовьте строку ASCIIZ с именем вызываемого программного файла и установите DS:DX на первый символ этой строки.
  3. Подготовьте блок параметров EXEC со всеми необходимыми полями.
  4. Сохраните текущие значения SS, SP, DS, ES и DTA в переменных, адресуемых через регистр CS (CS - это единственная точка для ссылок после того, как EXEC вернет управление от ребенка).
  5. Выдайте вызов EXEC с AL=0.
  6. Восстановите локальные значения SS и SP.
  7. Проверьте флаг CF, чтобы узнать, не было ли ошибки при EXEC.
  8. Восстановите DS, ES и локальную DTA, если необходимо.
  9. Проверьте код выхода через функцию 4dH WAIT (если надо).

Все открытые файлы дублируются, так что ребенок может обрабатывать данные как через описатели файлов, так и через стандартный в/в. режимы доступа описателей дублируются, но любые активные блокировки файлов не будут относиться к ребенку. См. функцию 5cH. после возврата из ребенка, векторы INT 22H Terminate, INT 23H Ctrl-Break и INT 24H Critical Error восстанавливаются в их предыдущие значения.

AL=3 LOAD: Эта подфункция используется для загрузки "оверлея".

DS:DX указывает на ASCIIZ имя файла, а ES:BX указывает на "LOAD"-версию блока параметров EXEC. Главное значение этой подфункции в том, что она считывает заголовок EXE и выполняет необходимые перемещения сегментов, как это требуется для программ .EXE.

Замечания:

Эта функция использует программу-загрузчик из COMMAND.COM, который транзитен в DOS 2.x (и, возможно, уже перекрыт программой). В этом случае возникнет ошибка, если DOS не найдет файл COMMAND.COM. Вы должны обеспечить корректную строку COMSPEC= в окружении перед вызовом этой функции.

Вместо разбора собственных FCB (как требуется для EPB), вы можете найти удобным загрузить и выполнить вторичную копию файла COMMAND.COM, используя опцию /C. например, чтобы выполнить программу FORMAT.COM, установите DS:DX на адрес строки ASCIIZ: "\command.com",0 и установите EPB+2 на сегмент и смещение следующей строки команд: 0eH,"/c format a:/s/4",0dH такой вторичный интерпретатор команд использует очень мало памяти (около 4K). Вы можете поискать в окружении DOS строку COMSPEC=, чтобы установить точное местоположение файла COMMAND.COM.


DOS Fn 4cH: завершить программу -- EXIT

  • AH = 4cH
  • AL = код выхода

Выход

  • нет = (неприменим)

Описание:

возвращает управление от порожденного процесса его родителю, устанавливая код выхода, который можно опросить функцией 4dH WAIT. Управление передается по адресу завершения в PSP завершающейся программы. векторы Ctrl-Break и Critical Error восстанавливаются к старым адресам, сохраненнмы в родительском PSP.

Замечание:

значение ERRORLEVEL (используемое в пакетных файлах DOS) можно использовать для проверки кода выхода самой последней программы.


DOS Fn 4dH: дать код выхода программы -- WAIT

  • AH = 4dH

Выход

  • AL = код выхода последнего завершившегося процесса
  • AH = 0 - нормальное завершение
  • AH = 1 - завершение через Ctrl-Break
  • AH = 2 - завершение по критической ошибке устройства
  • AH = 3 - завершение через функцию 31H KEEP

Описание:

возвращает код выхода последнего из завершившихся процессов. Эта функция возвращает правильную информацию только однажды для каждого завершившегося процесса.


DOS Fn 4eH: Найти 1-й совпадающий файл

  • AH = 4fH
  • DS:DX = адрес строки ASCIIZ с именем файла (допускаются ? и *)
  • CX = атрибут файла для сравнения

Выход

  • AX = код ошибки если CF установлен
  • DTA = заполнена данными (если не было ошибки)

Описание:

DS:DX указывает на строку ASCIIZ в форме: "d:\путь\имяфайла",0. Если диск и/или путь опущены, они подразумеваются по умолчанию. Обобщенные символы * и ? допускаются в имени файла и расширении. DOS находит имя первого файла в оглавлении, которое совпадает с заданным именем и атрибутом, и помещает найденное имя и другую информацию в DTA, как показано ниже:

Замечания:

Атрибут файла обычно используется во "включающем" поиске. если вас интересуют как файлы, так и оглавления, установите бит атрибута 4 (т.е. attr | 10H). См. атрибут файла для полной информации.

Типичная последовательность, используемая для поиска всех подходящих файлов:

  • используйте вызов 1aH, чтобы установить DTA на локальный буфер (или используйте умалчиваемую DTA в PSP по смещению 80H)
  • уст. CX=атрибут, DS:DX => ASCIIZ диск, путь, обобщенное имя
  • вызовите функцию 4eH (Найти 1-й)
  • если флаг CF указывает ошибку, вы закончили (нет совпадений)
  • уст. DS:DX => DTA (или на данные, которые вы скопировали из DTA после вызова функции 4eH)
  • повторять
    • обработать имя файла и данные по адресу DS:DX
    • вызвать функцию 4fH (Найти следующий)
    • пока Carry-флаг не покажет, что совпадений больше нет


DOS Fn 4fH: Найти следующий совпадающий файл

  • AH = 4fH
  • DS:DX = адрес данных, возвращенных предыдущей 4eH Найти 1-й файл

Выход

  • AX = код ошибки если CF установлен
  • DTA = заполнена данными

Описание:

DS:DX указывает на 2bH-байтовый буфер с информацией, возвращенной функцией 4eH Найти 1-й (либо DTA, либо буфер, скопированный из DTA).

Используйте эту функцию после вызова 4eH. следующее имя файла, совпадающее по обобщенному имени и атрибуту файла, копируется в буфер по адресу DS:DX вместе с другой информацией (см. функцию 4eH о структуре файловой информации в буфере, заполняемом DOS).


DOS Fn 54H: дать переключатель верификации DOS

  • AH = 54H

Выход

  • AL = 0 если верификация выключена (OFF)
  • AL = 1 если верификация включена (ON)

Описание:

Возвращает текущий статус верификации записи DOS. Если в AL возвращается 1, то DOS считывает обратно каждый сектор, записываемый на диск, чтобы проверить правильность записи. функция DOS 2eH позволяет установить/изменить режим верификации.


DOS Fn 56H: Переименовать/переместить файл

  • AH = 56H
  • DS:DX = адрес старого ASCIIZ имени (путь/имя существующего файла)
  • ES:DI = адрес нового ASCIIZ имени (новые путь/имя)

Выход

  • AX = код ошибки если CF установлен

Описание:

DS:DX и ES:DI указывают на строки ASCIIZ: "d:\путь\имяфайла",0. Старое имя DS:DX должно отвечать существующему файлу и не может содержать обобщенных символов. диск и путь необязательны (если опущены, они принимаются по умолчанию).

Новое имя ES:DI должно описывать НЕ существующий файл. если указан диск, он должен быть тем же, что и в старом имени. если диск или путь опущены, принимаются текущие умолчания.

Если старое и новое имя содержат разные пути (явно или принятые по умолчанию), то элемент оглавления для файла ПЕРЕМЕЩАЕТСЯ в оглавление, указанное в новом имени.

Замечание:

если ID диска в старом имени отличается от текущего диска DOS, не забывайте указывать такой же ID диска в новом имени.


DOS Fn 57H: установить/опросить дату/время файла

  • AH = 57H
  • AL = 0 чтобы получить дату/время файла
  • = 1 чтобы установить дату/время файла
  • BX = описатель файла (handle)
  • CX = (если AL=1) новая отметка времени в формате время/дата файла
  • DX = (если AL=1) новая отметка даты в формате время/дата файла

Выход

  • AX = код ошибки если CF установлен
  • CX = отметка времени файла в формате время/дата файла
  • DX = отметка даты файла в формате время/дата файла

Описание:

BX должен содержать описатель открытого файла (см. 3cH или 3dH ).

Укажите подфункцию, 0 или 1, в регистре AL. DX и CX задаются в формате памяти; например, младшие 8 бит даты находятся в DH.


DOS Fn 59H: дать расширенную информацию об ошибке

  • AH = 59H DOS 3.0+
  • BX = 0000H (номер версии: 0000H для DOS 3.0, 3.1 и 3.2)

Выход

  • AX = расширенный код ошибки (0, если не было ошибки)
  • BH = класс ошибки
  • BL = предлагаемое действие
  • CH = сфера (где произошла ошибка)

Описание:

используйте эту функцию, чтобы уточнить, что предпринять после сбоя функции DOS по ошибке (только DOS 3.0+ ). вызывайте ее:

  • в обработчике критических ошибок INT 24H
  • после любой функции INT 21H , возвратившей Carry-флаг
  • после вызова FCB-функции, возвратившей AL=0ffH

Версии:

Эта функция отсутствует в версиях до DOS 3.00. В DOS 2.x, когда флаг CF указывает на ошибку, используйте логику вашей программы, чтобы отреагировать на ошибку. В DOS 3.0+, когда функция возвращает CF=1, рекомендуем вам игнорировать код ошибки, возвращенный в AX, вызвать эту функцию и выполнить действие, предложенное в BL.


DOS Fn 5aH: создать уникальный временный файл

  • AH = 5aH DOS 3.0+
  • DS:DX = адрес строки ASCIIZ с диском и путем (заканчивается \)
  • CX = атрибут файла

Выход

  • AX = код ошибки если CF установлен и описатель файла (если нет ошибки)
  • DS:DX = (не изменяется) становится полным ASCIIZ-именем нового файла

Описание:

открывает (создает) файл с уникальным именем в оглавлении, указанном строкой ASCIIZ, на которую указывает DS:DX. COMMAND.COM использует эту функцию, когда создает временные "канальные" файлы, используемые при переназначении ввода-вывода. Описание пути должно быть готово к присоединению в его конец имени файла. Вы должны обеспечить минимум 12 байт в конце строки. Сама строка должна быть заполнена в одной из форм:

  • "d:\путь\",0 (указаны диск и путь)
  • ИЛИ "d:",0 (умалчиваемое оглавление диска)
  • ИЛИ "d:\",0 (корневое оглавление диска)
  • ИЛИ "",0 (умалчиваемые диск и оглавление)

После возврата строка DS:DX будет дополнена именем файла.

Замечания:

DOS создает имя файла из шестнадцатеричных цифр, получаемых из текущих даты и времени. если имя файла уже существует, DOS продолжает создавать новые имена, пока не получит уникальное имя. создаваемые таким способом файлы - по существу НЕ ВРЕМЕННЫЕ, и их следует удалять посредством функции DOS 41H , когда они не нужны.

Версии:

доступна, начиная с DOS 3.0


DOS Fn 5bH: создать новый файл

  • AH = 5bH DOS 3.0+
  • DS:DX = адрес строки ASCIIZ с именем файла
  • CX = атрибут файла

Выход

  • AX = код ошибки если CF установлен и описатель файла если ошибок нет

Описание:

DS:DX указывает на строку ASCIIZ в форме: "d:\путь\имяфайла",0. Если диск и/или путь опущены, они принимаются по умолчанию. Этот вызов идентичен функции DOS 3cH CREATE, с тем исключением, что он вернет ошибку, если файл с заданным именем уже существует. Файл открывается для чтения/записи в совместимом режиме доступа


DOS Fn 5cH: блокировать/разблокировать доступ к файлу

  • AH = 5cH DOS 3.0+
  • AL = подфункция: 0 = заблокировать область файла
  • = 1 = разблокировать ранее захваченную область
  • BX = описатель файла (handle)
  • CX:DX = смещение ((CX * 65536) + DX) от начала файла
  • SI:DI = длина блокируемой области ((SI * 65536) + DI) байт

Выход

  • AX = код ошибки если CF установлен

Описание:

блокирует или освобождает доступ к участку файла, идентифицируемого описателем в BX. область файла, начинающаяся по логическому смещению CX:DX и имеющая длину SI:DI, блокируется (захватывается) или разблокируется (освобождается). смещение и длина обязательны. Разделение файлов ДОЛЖНО быть активизировано (командой SHARE), иначе функция вернет код ошибки "неверный номер функции." Блокировка действует на операции чтения, записи и открытия со стороны порожденного или конкурирующего процесса. при попытке такого доступа (и режиме доступа , определенном при OPEN как "режим разделения", который запрещает такой доступ), DOS отвергает операцию через вызов INT 24H (обработчик критических ошибок) после трех попыток. DOS при этом выдает сообщение "Abort, Retry, Ignore". Рекомендуемое действие - НЕ пытаться читать файл и ожидать кода ошибки. Вместо этого попытайтесь заблокировать область и действуйте в соответствии с кодом возврата. это позволяет избежать довольно неустойчивого состояния DOS, связанного с выполнением INT 24H. Блокировка за концом файла не является ошибкой. Вы можете захватить весь файл, задав CX=0, DX=0, SI=0ffffH, DI=0ffffH и AL=0. при освобождении, смещение и длина участка должны точно совпадать со смещением и длиной захваченного участка.

Замечания:

Дублирование описателя через 45H или 46H дублирует и блокировки. Даже если во время OPEN выбран режим доступа Inherit, механизм блокировки не даст никаких привилегий доступа порожденным процессам, созданным функцией 4bH EXEC (они трактуются как отдельные). Важно, чтобы все блокировки файла были сняты до завершения программы. если вы используете блокировку, особо отслеживайте вызовы INT 23H (выход Ctrl-Break) и INT 24H (выход по критической ошибке), чтобы снять блокировки до действительного завершения программы. Рекомендуется освобождать блокировки как можно скорее. всегда блокируйте, обрабатывайте файл и освобождайте блокировку одной операцией.

Версии:

доступна, начиная с DOS 3.0


DOS Fn 5eH: Разные сетевые функции

  • AH = 5eH DOS 3.1+
  • AL = подф.: 0=дать имя машины (узла) в сети
  • AL = 2=установить стартовую строку сетевого принтера
  • AL = 3=извлечь стартовую строку сетевого принтера
  • прочие = (зависят от подфункции)

Выход

  • AX = код ошибки если CF установлен
  • прочие = (зависят от подфункции)

Описание:

Эти функции доступны при установленной IBM PC Network Program.

Версии:

доступны, начиная с DOS 3.1

· подф. 00H: Извлекает имя машины (узла), как оно известно в сети.

· в ход: DS:DX=> буфер пользователя для ASCIIZ сетевого имени

· выход:

  • DS:DX=> буфер, содержащий сетевое имя
  • CH= 0=имя не определено; иначе=имя определено
  • CL= номер имени NETBIOS (если CH ненулевой)
  • AX= код ошибки если CF установлен

· Замеч: Сетевое имя - 15-симв. (дополненная пробелами) строка ASCIIZ

· подф. 02H: Задает настроечную строку, посылаемую на принтер каждый раз, когда эта машина выдает результаты на сетевой принтер.

· в ход:

  • DS:SI=> буфер, содержащий настроечную строку (до 64 байт)
  • CX= длина настроечной строки
  • BX= индекс в списке назначений, отвечающий принтеру

· выход: AX= код ошибки если CF установлен

· подф. 03H: Извлекает настроечную строку принтера, заданную ранее посредством DOS Fn 5eH подф. 02H.

· вход:

DS:DI=> 64-байтовый буфер пользователя для результата

BX= индекс принтера в списке назначений

· выход:

  • ES:DI=> буфер, заполненный настроечной строкой
  • CX= длина настроечной строки
  • AX= код ошибки если CF установлен

· Замеч: Поскольку индекс в списке назначений может измениться в любой момент, используйте функцию 5fH подф. 02H, чтобы получить индекс непосредственно перед вызовом этой функции.


DOS Fn 5fH: переназначение устройств в сети

  • AH = 5fH DOS 3.1+
  • AL = подф.: 2=получить элемент списка переназначений устройств
  • = 3=переназначить сетевое устройство
  • = 4=отменить переназначение сетевого устройства
  • прочие = (зависят от подфункции)

Выход

  • AX = код ошибки если CF установлен

Описание:

Эти функции доступны при установленной IBM PC Network Program.

Версии:

доступны, начиная с DOS 3.1

· подф. 02H: Извлекает элемент из списка переназначений сетевых устройств.

· в ход:

  • DS:DI=> 128-байтовое ASCIIZ локальное имя устр. ("LPT1",0)
  • ES:DI=> 128-байтовый буфер с ASCIIZ сетевым именем
  • BX= индекс в списке назначений

· выход:

  • DS:DI=> ASCIIZ локальное имя устройства (напр., "LPT1",0)
  • ES:DI=> ASCIIZ сетевое имя
  • BL= тип устр: 3=принтер; 04=файл 'устройство'
  • BH= статус устр: бит 0=1 -неверное устр.; 0=верное
  • CX= сохраненный параметр (при NETBIOS, всегда 0)
  • AX= код ошибки если CF установлен
  • DX,BP = (изменены)

· Замеч: обычно эту функцию вызывают с BX=0, затем повторяют вызовы, увеличивая значение BX, пока DOS не вернет ошибку 12H (больше нет файлов).

· подф. 03H: этот вызов определяет имена оглавлений для сети и перенаправляет доступ на сетевые принтеры. Замеч: доступ к принтеру переназначается на уровне ROM-BIOS INT 17H.

· вход:

  • DS:SI = ASCIIZ имя исходного устройства
  • ES:DI = ASCIIZ назначение (сетевой путь с паролем)
  • BL= тип устр: 03=принтер; 04=файл 'устройство'
  • CX= параметр для вызывающего (задавайте 0 для NETBIOS)

· выход: AX= код ошибки если CF установлен

· Замеч: если BL=03, то источник задает ASCIIZ-имя принтера (например, "LPT1",0). Назначение кодируется в форме: [\\computername\{shortname|printdevice}],0,[password],0. Если пароль начинается с 00, считается, что пароля нет. Если BL=04, то источник задает ASCIIZ-имя диска (например, "F:",0), а назначение - ASCIIZ-имя пути. после вызова этой функции, локальные обращения к этому диску переназначаются на выбранные имя компьютера и путь.

· подф. 04H: Отменить сетевое переназначение для указанного устройства.

· в ход: DS:SI=> ASCIIZ-имя устройства или ID диска

· выход: AX= код ошибки если CF установлен

· Замеч: если DS:SI указывает на PRN, LPT1, LPT2 или LPT3, и устройство связано с сетью, то сетевое обслуживание этого устройства прекращается. Если DS:SI указывает на ID диска и пароль (например, "F:",0,"mypswrd",0), то переназначение этого диска прекращается, и ID диска восстанавливает свое предыдущее значение.


DOS Fn 62H: дать адрес PSP

  • AH = 62H DOS 3.0+

Выход

  • BX = сегментный адрес PSP выполняющейся программы

Описание:

Эта функция возвращает в BX адрес PSP текущей программы. используется, чтобы получить адрес параметров командной строки, адрес окружения DOS и другой полезной информации в PSP.

Версии:

доступна, начиная с DOS 3.0


Недокументированные возможности MS-DOS - Функция 13h прерывания 21h. Недокументированные возможности.

Функция 13h прерывания 21h. Недокументированные возможности.

Функция 13h прерывания 21h относится к серии функций, выполняющих операции с файлами с использованием FCB. Она удаляет файл или группу файлов.

Эта функция имеет один недокументированный случай, когда расширенный FCB использует имя файла ??????????? и атрибут файла 1Fh. При этой специфической комбинации функция 13h удаляет все файлы в текущем каталоге, включая файлы с атрибутами "только для чтения", "том" и "каталог". Чтобы усугубить положение, эта функция заменяет первый символ в имени удаленного файла на 0, а не на обычный 0E5h. Это вводит в заблуждение многие утилиты восстановления файлов.

Таким образом, будучи примененной в головном каталоге, она эффективно удаляет все файлы на диске. Так как подкаталоги являются не более чем специальными файлами, содержащими информацию о каталоге, исключения для них не делается. В результате это препятствует всякому доступу к файлам, которые были в тех подкаталогах, включая любые подкаталоги большей глубины. Следует заметить, что файлы в тех подкаталогах не удаляются и занимаемое ими на диске место остается занятым. Удаляется только информация о них в каталогах. Следовательно, утилита CHKDSK сообщит об этих неучтенных файлах как о кластерах, не включенных в пространство диска (потерянных). Конечно, эти удаленные файлы возможно восстановить, но только усердной работой с дисковым редактором.

Такое поведение MS-DOS по меньшей мере странно. Обычно только внутренние процедуры MS-DOS могут изменять или удалять файлы, помеченные атрибутом "подкаталог". То, что функции, оперирующей с FCB, дозволено удалять эти файлы - невероятная причуда MS-DOS.

;----------------------------------------------------------------------
;       Пример использования недокументированново свойства функции 13h
;       прерывания 21h.
;       НИ В КОЕМ СЛУЧАЕ НЕ ВЫПОЛНЯЙТЕ ЭТОТ ПРИМЕР НА ЖЕСТКОМ ДИСКЕ:
;       ЭТО МОЖЕТ ПРИВЕСТИ К НЕПРЕДСКАЗУЕМЫМ ПОСЛЕДСТВИЯМ. ЕСЛИ УЖ ЕСТЬ
;       ГОРЯЧЕЕ ЖЕЛАНИЕ ИСПЫТАТЬ ЕЕ, ВЫДЕЛИТЕ ДЛЯ ЭТОЙ ЦЕЛИ ОТДЕЛЬНУЮ
;       ДИСКЕТУ.
;-----------------------------------------------------------------------

               mov     ax, offset RETURN     ; Взять смещение адреса возврата
               push    ax                    ; Занести в стек флаги, сегмент
               push    cs                    ;    и смещение адреса возврата
               pushf                         ;    в обратном порядке.
               mov     cl, 13h               ; Функция: удалить по FCB
               mov     dx, offset FCB        ; Расширенный FCB
               push    cs                    ; Для уверенности, что DS
               pop     ds                    ;    указывает на текущий код.
               jmp     dword ptr ALT_DOS_PTR ; Выполнить функцию.

RETURN:        mov     ah, 4Ch               ; Завершить процесс через DOS.
               int     21h                   ;

ALT_DOS_PTR    dw      00C0h, 0000           ; Адрес для перехода в альтер-
                                            ;    нативный обработчик
FCB            db      0FFh           ; Расширенный FCB
               db      5 dup (0)       ; Зарезервированные байты
               db      1Fh             ; Установлены все биты атрибута файла
               db      0               ; Номер дискового устройства
               db      "???????????"   ; Искать все файлы
               db      19h dup (0)     ; Остальная часть FCB

;--------------------------------------------------------------------------

[ Оглавление ]

Комментарии пользователей (всего 1)

Александр / 07 января 2005, 12:06:49

Да....
Интересная заметка, приму к сведению
Спасибо Вам за выкладывание на сайте такой инфы


Прерывания DOS и BIOS

/ DOS

Прерывания BIOS

  • Двоичная система счисления. Бит и байт. Сегментация памяти
  • Недокументированные возможности MS-DOS

· 00h: Деление на ноль.

· 01h: Пошаговое.

· 02h: Немаскируемое.

· 03h: Точка прерыв.

· 04h: Переполнение.

· 05h: Печать экрана.

· 06h: (резерв)

· 07h: (резерв)

· 08h: Таймер.

· 09h: Клавиатура.

· 0Ah-0dh: (hdwr ints)

· 0Eh: Дискета.

· 0Fh: (hdwr int)

· 10h: Видео сервис.

· 11h: Список оборудования.

· 12h: Размер исп.памяти.

· 13h: Дисковый в/в.

· 14h: В/в через последовательный порт

· 15h: Расшир.сервис AT.

· 16h: В/в клавиатуры.

· 17h: В/в принтера.

· 18h: ROM-BASIC.

· 19h: Загрузка.

· 1Ah: В/в таймера.

· 1Bh: Прерывание клавиатуры.

· 1Ch: Пользовательское прерывание по таймеру

· 1Dh: Видео параметры

· 1Eh: Параметры дискет

· 1Fh: Символы графики

Прерывания DOS

  • 20h: Завершить программу
  • 21h: Сервис DOS
  • 25h/26h: Абсолютные чтение/запись диска
  • 27h: Завершиться, но остаться резидентным
  • 28h: Квант времени DOS (НЕТ В ДОКУМЕНТАЦИИ)
  • 2eh: Выполнить команду DOS (НЕТ В ДОКУМЕНТАЦИИ)
  • 2fh: Мультиплексное прерывание (спулинг печати)

Адресные указатели (не используются как прерывания)

  • 22h: Адрес завершения
  • 23h: Адрес Control-Break
  • 24h: Адрес обработчика критических ошибок

Оставить комментарий

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.


Недокументированные возможности MS-DOS

  • Комментарии к небольшой серии статей о недокументированных возможностях MS-DOS.
  • Альтернативный обработчик прерывания int 21h
  • Функция 13h прерывания 21h - недокументированные возможности.
  • Прерывания 30h и 31h
  • Содержимое psp: ячейки 05h-09h - описание действий для вызова функций DOS в стиле CP/M


Недокументированные возможности MS-DOS - Прерывания 30h и 31h

Прерывания 30h и 31h

Прерывания 30h и 31h не используются в DOS и о них ничего не говорится в обычных руководствах программиста по DOS. Строго говоря, их вообще нельзя назвать прерываниями и тем более пытаться их выполнить. Ни к чему хорошему это не приведет, поскольку ячейки памяти, зарезервированные для векторов этих двух прерываний (0:00C0 - 0:00C7) не содержат, как обычно, адресов процедур, выполняющих обработку прерываний.

Вместо зтого, начиная с адреса 0:00C0 (адрес вектора прерывания 30h) располагается команда JMP FAR seg:off, которая указывает на альтернативный обработчик прерывания 21h. В результате, зная правила передачи параметров и и другой необходимой для обработчика прерывания информации, можно осуществить прямой доступ в DOS, не генерируя прерывание 21h, а просто выполняя переход на описанную команду.

Естественно, зтот способ позволяет получить доступ только к оригинальному обработчику прерывания 21h. И если программой был установлен другой обработчик этого прерывания, управление указанным способом ему передано не будет. Во многих случаях зто, конечно, очень удобно. Однако нельзя забывать, что это еще более удобно для вирусов, желающих, чтобы их обращения к функциям DOS осталось незамеченным.

Своим существованием эта команда обязана желанию разработчиков PC-DOS и MS-DOS обеспечить совместимость с операционной системой CP/M, где для вызова функции DOS было необходимо выполнить команду CALL 0005, предварительно загрузив номер функции в регистр CL. Этот вызов выполнял команду, находяшуюся по смещению 5 в PSP, а та, в свою очередь, вызывала DOS.

Описанный способ доступа к DOS существует в PC-DOS, начиная с версии 1.1, и в большинстве версий MS-DOS.

;----------------------------------------------------------------------------
;       Пример вызова функции DOS через альтернативный обработчик
;       прерывания 21h.

               mov     ax, offset RETURN     ; Взять смещение адреса возврата
               push    ax                    ; Занести в стек флаги, сегмент
               push    cs                    ;    и смещение адреса возврата
               pushf                         ;    в обратном порядке.
               mov     cl, 9                 ; Функция: показать строку.
               mov     dx, offset MESSAGE    ; Загрузить адрес сообщения.
               push    cs                    ; Для уверенности, что DS
               pop     ds                    ;    указывает на текущий код.
               jmp     dword ptr ALT_DOS_PTR ; Выполнить функцию.

RETURN:        mov     ah, 4Ch               ; Завершить процесс через DOS.
               int     21h                   ;

ALT_DOS_PTR    dw      00C0h, 0000           ; Адрес для перехода в альтер-
                                            ;    нативный обработчик
MESSAGE        db      0Dh, 0Ah, "Example of backdoor MS-DOS "
               db      "function call.", 0Dh, 0Ah, 7, "$"

[ Оглавление ]


Функции BIOS - INT 00H: Переполнение при делении.

INT 00H: Переполнение при делении.

Процессор автоматически вызывает это прерывание после выполнения команд DIV или IDIV, если результат операции деления (частное) не умещается в поле результата.

Эта ситуация включает и деление на 0. Например:

         mov   ax,4000H  ;делимое
         mov   bl,2      ;делитель - байт, поэтому частное - тоже байт (AL)
         div   bl        ;4000H/2 = 2000H, что не умещается в байте AL
                         ;  поэтому выполняется прерывание INT 00H

или просто:

         mov   bx,0
         div   bx        ;любое деление на 0


Функции BIOS - INT 01H: Пошаговое прерывание.

INT 01H: Пошаговое прерывание.

Если установлен флаг трассировки процессора (TF=1), CPU вызывает это прерывание после каждрй команды.

Отладчики, которые позволяют вам осуществлять пошаговое выполнение программы, используют это прерывание, чтобы перехватывать управление и выдавать регистры, память и т.п.

Трассировка отключается (TF=0) при выполнении любой команды INT, так что само INT 01H выполняется не в пошаговом режиме. После выхода из прерывания (через IRET) все флаги восстанавливаются, так что следующая команда вновь вызовет пошаговое прерывание.

Обычный способ начать трассировку - это поместить в стек слово, содержащее все нужные флаги (включая TF=1), поместить в стек требуемые значения CS и IP, а затем выполнить IRET, чтобы начать трассировку с указанного адреса.


Функции BIOS - INT 02H: Немаскируемое прерывание.

INT 02H: Немаскируемое прерывание.

Немаскируемое прерывание (NMI) - это единственное прерывание, не запрещаемое командой CLI. Поэтому его можно использовать в специальных случаях, которые требуют немедленного действия.

Это прерывание спроектировано для обработки катастрофических ситуаций, таких как сбой питания. В системе, обеспечивающей целостность данных, NMI может, например, выводить образ памяти на диск с целью избежать потери данных. В стандартной системе PC BIOS, NMI аппаратно вызывается в случае "ошибки четности" памяти. Когда это происходит, PC зависает. А теперь скажите мне, чувствуете ли вы себя в безопасности, зная, что будет потеряна вся ваша память, а не несколько бит?

Сопроцессор 8087/80287 подключен к линии NMI, и вызывает прерывание, когда встречает условие исключения (например, деление на 0). Обычно вы должны читать порт 64H, чтобы выяснить, не произошел ли сбой памяти, и если нет, выполнить FNSAVE, чтобы установить причину сбоя 8087, а затем FNCLX для устранения ошибки.


Функции BIOS - INT 03H: Прерывание по точке.

INT 03H: Прерывание по точке.

Вектор прерывания INT 03H используется отладчиками, чтобы перехватывать управление, когда программа достигает указанного пользователем адреса.

Код операции для INT 03H занимает один байт (0ccH), так что им можно временно замещать начало любой команды, не боясь запортить следующую команду.


Функции BIOS - INT 04H: Прерывание по переполнению.

INT 04H: Прерывание по переполнению.

Вектор INT 04H может использоваться как один из способов оптимизации программ, содержащих большое число арифметических операций.

Выданная после любой арифметической операции, команда INTO осуществляет проверку на арифметическое переполнение, и, если флаг переполнения взведен (OF=1), вызывает прерывание INT 04H.

Вам, возможно, встречался код типа следующего:

         mov     ax,var_1
         add     ax,var_2
         into              ;2-байтовая команда проверки на переполнение
     ... и т.д. ...        ;либо не было переполнения, либо оно уже обработано


Функции BIOS - INT 05H: Печать экрана.

INT 05H: Печать экрана.

INT 05H, к ужасу фирмы Intel (которая считала его зарезервированным прерыванием), используется в PC для вызова программы ROM BIOS, печатающей экран.

Это прерывание вызывается обработчиком прерывания INT 09H при распознавании клавиши PrtSc. Оно может также вызываться из программы, и вы можете перехватывать это прерывание, если хотите предоставить свою программу печати экрана.

В "EGA" BIOS есть функция, заменяющая обычное средство Print-Screen программой, которая может обрабатывать различные экранные фонты. См. INT 10H Подф. 12H.

Команда DOS "Graphics" заменяет эту программу своей, которая выдает графический экран (в точечном представлении) на IBM-совместимый графический принтер.


Функции BIOS -

INT 08H: прерывание от таймера

Зто аппаратно генерируемое прерывание (IRQ 0) вызывается по каждому тику часов реального времени PC. Часы тикают каждые 55мс, или около 18.2 раз в секунду. Код ROM-BIOS для этого прерывания обновляет значение часов на 0:046 сек. этот код также выключает двигатели гибких дисков по истечении примерно двух секунд без операций ввода/вывода.

Если вы хотите использовать это прерывание для обработки событий, зависящих от времени, вы должны предусмотреть код, сообщающий системе, когда прерывание закончено. Магическая последовательность такова:

         mov     al,20H     ;послать сигнал конец-прерывания
         out     20H,al     ; контроллеру прерываний 8259

большинство программ используют для этого ROM-BIOS. например, вначале программа пользователя сохраняет вектор ROM-BIOS в переменной с именем cs:[saved_int8]. затем по каждому прерыванию INT 08H выполняется следующий код:

        pushf                              ;имитировать INT
        call  dword ptr cs:[saved_int8]    ;выполнить нормальную обработку
        cmp   cs:my_var,test_value         ;теперь сделать свои черные дела
    ... и т.д. ...
        iret    ;возврат в прерванную прикладную программу "переднего плана"


Функции BIOS - INT 09H: прерывание от клавиатуры.

INT 09H: прерывание от клавиатуры.

Это аппаратно генерируемое прерывание (IRQ 1) выполняется при каждом нажатии и отпускании клавиши. код ROM-BIOS интерпретирует это, сохраняя значения в буфере клавиатуры по адресу 0:041e. Он также обрабатывает специальные случаи клавиш PrtSc и SysReq, и отслеживает состояние клавиш Shift и различных Lock.

Резидентные popup-программы, которые обычно предусматривают "кнопку вызова", перехватывают INT 09H и проверяют на определенный ключ примерно так:

         push    ax
         in      al,60H             ;читать ключ
         cmp     al,POP_KEY         ;это кнопка вызова?
         je      do_pop             ; да, активизировать popup
                                    ;  нет, уйти на исходный обработчик
         pop     ax
         jmp     cs:[int9_vect]     ;переход на первоначальный обработчик
do_pop:  ;------ следующий код необходим для отработки аппаратного прерывания
         in      al,61H             ;взять значениe порта управления клавиатурой
         mov     ah,al              ; сохранить его
         or      al,80h             ;установить бит разрешения для клавиатуры
         out     61H,al             ; и вывести его в управляющий порт
         xchg    ah,al              ;извлечь исходное значение порта
         out     61H,al             ; и записать его обратно
         mov     al,20H             ;послать сигнал "конец прерывания"
         out     20H,al             ; контроллеру прерываний 8259
         ;------ дальше - прочие проверки, и наконец - активизация popup


Функции BIOS - INT 0eH: прерывание от дискеты

INT 0eH: прерывание от дискеты

INT 0eH - это аппаратно генерируемое прерывание (IRQ 6), вызываемое контроллером флоппи-дисков.

Код ROM-BIOS взводит бит 7 в переменной BIOS "seek_status" (0:043e), указывая, что запущена операция поиска на дискете. прерывание INT 13H использует этот флаг, чтобы определить, не требуется ли рекалибрация контроллера перед следующей операцией.


Функции BIOS - INT 10H: видео сервис.

INT 10H: видео сервис

Здесь детализированы функции INT 10H стандартного видеосервиса ROM-BIOS.

AH  сервис
--- ----------------------------------------------------------------------------
00H уст. видео режим. Очистить экран, установить поля BIOS, установить режим.
    вход:  AL=режим
           AL  Тип      формат   цвета          адаптер  адрес монитор
           === =======  =======  =============  =======  ====  =================
            0  текст    40x25    16/8 полутона  CGA,EGA  b800  Composite
            1  текст    40x25    16/8           CGA,EGA  b800  Comp,RGB,Enhanced
            2  текст    80x25    16/8 полутона  CGA,EGA  b800  Composite
            3  текст    80x25    16/8           CGA,EGA  b800  Comp,RGB,Enhanced
            4  графика  320x200  4              CGA,EGA  b800  Comp,RGB,Enhanced
            5  графика  320x200  4 полутона     CGA,EGA  b800  Composite
            6  графика  640x200  2              CGA,EGA  b800  Comp,RGB,Enhanced
            7  текст    80x25    3 (b/w/bold)   MA,EGA   b000  TTL Monochrome
           0dH графика  320x200  16             EGA      A000  RGB,Enhanced
           0eH графика  640x200  16             EGA      A000  RGB,Enhanced
           0fH графика  640x350  3 (b/w/bold)   EGA      A000  Enhanced,TTL Mono
           10H графика  640x350  4 или 16       EGA      A000  Enhanced
       8,9,0aH  режимы PCjr
       0bH,0cH  (резервируется для EGA BIOS)
          замечание: для EGA и Jr можно добавить 80H к AL, чтобы
               инициализировать видео режим без очистки экрана.
--- ----------------------------------------------------------------------------
01H уст. размер/форму курсора (текст). курсор, если он видим, всегда мерцает.
    вход:  CH = начальная строка (0-1fH; 20H=подавить курсор)
           CL = конечная строка (0-1fH)
--- ----------------------------------------------------------------------------
02H уст. позицию курсора. установка на строку 25 делает курсор невидимым.
    вход:  BH = видео страница
           DH,DL = строка, колонка (считая от 0)
--- ----------------------------------------------------------------------------
03H читать позицию и размер курсора
    вход:  BH = видео страница
   выход:  DH,DL = текущие строка,колонка курсора
           CH,CL = текущие начальная,конечная строки курсора (см. функцию 01H)
--- ----------------------------------------------------------------------------
04H читать световое перо
    вход:  нет
   выход:  AH = триггер (0=нет значений; 1=возвращены значения светового пера)
           DH,DL = строка,колонка символа (текст)
           BX = колонка точки (графика)
           CH = строка точки (для графики EGA возвращается в CX)
--- ----------------------------------------------------------------------------
05H выбрать активную страницу дисплея
    вход:  AL = номер страницы (большинство программ использует страницу 0)
--- ----------------------------------------------------------------------------
06H листать окно вверх (или очистить). Листать на 1 или более строк вверх.
    вход:  CH,CL = строка,колонка верхнего левого угла окна (считая от 0)
           DH,DL = строка,колонка нижнего правого угла окна (считая от 0)
           AL = число пустых строк, вдвигаемых снизу (0=очистить все окно)
           BH = видео атрибут, используемый для пустых строк
--- ----------------------------------------------------------------------------
07H листать окно вниз (вдвинуть пустые строки в верхнюю часть окна)
    вход:  (аналогично функции 06H)
--- ----------------------------------------------------------------------------
08H читать символ/атрибут в текущей позиции курсора
    вход:  BH = номер видео страницы
   выход:  AL = прочитанный символ
           AH = прочитанный видео атрибут (только для текстовых режимов)
--- ----------------------------------------------------------------------------
09H писать символ/атрибут в текущей позиции курсора
    вход:  BH = номер видео страницы
           AL = записываемый символ
           CX = счетчик (сколько экземпляров символа записать)
           BL = видео атрибут (текст) или цвет (графика)
                (графические режимы: +80H означает XOR с символом на экране)
--- ----------------------------------------------------------------------------
0aH писать символ в текущей позиции курсора
    вход:  BH = номер видео страницы
           AL = записываемый символ
           CX = счетчик (сколько экземпляров символа записать)
--- ----------------------------------------------------------------------------
0bH выбрать цвет палитры/бордюра (CGA-совместимые режимы)
    вход:  BH = 0: (текст) выбрать цвет бордюра
                   BL = цвет бордюра (0-1fH; от 10H до 1fH - интенсивные)
           BH = 1: (графика) выбрать палитру
                   BL = 0: палитра green/red/brown
                   BL = 1: палитра cyan/magenta/white
--- ----------------------------------------------------------------------------
0cH писать графическую точку (слишком медленно для большинства приложений!)
    вход:  BH = номер видео страницы
           DX,CX = строка,колонка
           AL = значение цвета (+80H означает XOR с точкой на экране)
--- ----------------------------------------------------------------------------
0dH читать графическую точку (слишком медленно для большинства приложений!)
    вход:  BH = номер видео страницы
           DX,CX = строка,колонка
   выход:  AL = прочитанное значение цвета
--- ----------------------------------------------------------------------------
0eH писать символ на активную видео страницу (эмуляция телетайпа)
    вход:  AL = записываемый символ (использует существующий атрибут)
           BL = цвет переднего плана (для графических режимов)
--- ----------------------------------------------------------------------------
0fH читать текущий видео режим
    вход:  нет
   выход:  AL = текущий режим (см. функцию 00H)
           AH = число текстовых колонок на экране
           BH = текущий номер активной страницы дисплея
--- ----------------------------------------------------------------------------
10H-12H  См.  EGA BIOS сервис
--- ----------------------------------------------------------------------------
13H писать строку ¦AT¦  EGA  Выдает строку в позиции курсора. символы 0dH
    (CarRet), 0aH (LineFeed), 08H (backspace) и 07H (Beep) трактуются как
    команды управления и не высвечиваются.
    вход:   ES:BP => выводимая строка (спецформат для AL=2 и AL=3)
            CX = длина строки (подсчитываются только символы)
            DH,DL = строка,колонка начала вывода
            BH = номер страницы
            AL = код подфункции:
                 0 = использовать атрибут в BL; не трогать курсор
                 1 = использовать атрибут в BL; курсор - в конец строки
                 2 = формат строки: char,attr, char,attr...; не трогать курсор
                 3 = формат строки: char,attr, char,attr...; передвинуть курсор
--------------------------------------------------------------------------------
подфункции 10H-13H: EGA BIOS сервис        данные BIOS    функции ROM-BIOS

                               EGA BIOS сервис

Эти функции устанавливаются в процессе ROM-Scan при наличии платы EGA .
См. Детали видео сервиса подф. 00H о видео режимах, применимых к EGA.
См. порты в/в EGA о прямом доступе к средствам платы EGA.
AH  сервис
--- ----------------------------------------------------------------------------
10H установить регистры палитры для EGA
    Выбирает цвета, используемые данным атрибутом экрана. умалчиваемые цвета -
    те же, что используются с CGA (см. атрибуты экрана ).
    вход:  AL = 0: уст. один регистр палитры
                   BL = регистр (идентифицирует 4-битовый цвет; 0-15)
                   BH = значение регистра (6-битовый rgbRGB выдаваемый цвет)
           AL = 1: уст. регистр бордюра. Note: not much of a border.
                   BH = значение регистра
           AL = 2: уст. все регистры палитры и регистр бордюра
                   ES:BX => 17 байт (регистры палитры и регистр бордюра)
           AL = 3: выбрать интенсивность или мерцание
                   BL = 0: интенсивность фона (16 возможных цветов фона)
                   BL = 1: мерцание (8 цветов фона + мерцание переднего плана)
           значения регистра палитры для подфункций 0,1,and 2:
           --7-T-6-T-5-T-4-T-3-T-2-T-1-T-0-¬
           ¦не исп.¦ r   g  b/I  R   G   B ¦ (6 бит = 64 возможных цвета)
           L---+---+---+---+-T-+---+---+----
                             L= действует как интенсивность для режимов CGA
--- ----------------------------------------------------------------------------
11H EGA character generator functions.  Resets video variables without change
    to the current values in the regen buffer (ie, the screen is not cleared).
    вход:  AL = 0: load user-defined text-mode display font
                   ES:BP => user font table
                   CX = count of character patterns to store
                   DX = character offset (font load starts at this ASCII value)
                   BL = font block to load (0 to 4; 4 if 256K EGA memory)
                   BH = count of bytes per character pattern (eg, 8 or 14)
           AL = 1: load ROM 8x14 character font
                   BL = font block to load (0-4)
           AL = 2: load ROM 8x8 double-dot character font
                   BL = font block to load (0-4)
           AL = 3: set block specifier (enables two of the four 256-char sets)
                   The second set of 256 chars is selected by attribute bit 3.
                   (in other words, if you select a "foreground color" above 7,
                    the EGA displays the secondary font).
                   BL = font block selector (4 bits, 0-0fH)
                   --7-T-6-T-5-T-4-T-3-T-2-T-1-T-0-¬
                   ¦    not used   ¦block# ¦block# ¦
                   L---+---+---+---+---+---+---+----
                                     L=T=-   L===¦== selected when attr bit 3=0
                                       L============ used when attr bit 3=1
    ----------------------------------------------------------------------------
           Sub-functions 10H,11H,and 12H expect page 0 to be active and should
           be used directly after a mode reset.  These recalculate rows and
           columns and reprogram several CRTC registers, including the cursor
           registers.
           AL=10H: load user-defined text-mode display font (see SubFn 00H)
           AL=11H: load ROM 8x14 character font (see SubFn 01H)
           AL=12H: load ROM 8x8 double-dot character font (see SubFn 02H)
    ----------------------------------------------------------------------------
           AL=20H: set up user character font for graphics modes
                   ES:BP => 2048-byte table of 8x8 character set for INT 1fH
           AL=21H: set up user character font for graphics modes
                   ES:BP => table of 8x8 character set for INT 44H
                   CX = points (bytes per character)
                   BL = screen rows code
                        0 = user-specified
                            DL = character rows on screen
                        1 = 0eH (14 character rows on screen)
                        2 = 19H (25 character rows on screen)
                        3 = 2bH (43 character rows on screen)
           AL=22H: set up ROM 8x14 character font for graphics modes
                   BL = screen rows code (see above)
           AL=23H: set up ROM 8x8 double-dot character font for graphics modes
                   BL = screen rows code (see above)
    ----------------------------------------------------------------------------
           AL=30H: Get EGA information
                   BH = table pointer request code
                        0 = return ES:BP => current INT 1fH graphics font addr
                        1 = return ES:BP => current INT 44H graphics font addr
                        2 = return ES:BP => ROM 8x14 font table addr
                        3 = return ES:BP => ROM 8x8 double dot font table addr
                        4 = return ES:BP => ROM 8x8 double dot addr (top)
                        5 = return ES:BP => ROM 9x14 alternate table addr
           выход:  CX = font points (font-definition bytes per character)
                   DL = screen rows
--- ----------------------------------------------------------------------------
12H EGA special functions (Alternate Select)
    вход:  BL=10H: return EGA information
   выход:          BH = mode (0=color; 1=monochrome)
                   BL = memory size code (0=64K; 1=128K; 2=192K; 3=256K)
                   CH = feature bits (values of those unused RCA connectors)
                   CL = switch settings (adaptor/display primary/secondary)
    вход:  BL=20H: select alternate print-screen routine (be sure to use this
                   every time you change the number of screen rows).
--- ----------------------------------------------------------------------------
13H write string ¦AT¦  EGA  Displays a string at a selected cursor position.
    Characters 0dH (CarRet), 0aH (LineFeed), 08H (bksp), and 07H (Beep) are
    treated as control commands and are not displayed.
    вход:   ES:BP => string to display (special format for AL=2 and AL=3)
            CX = length of string (character count only)
            DH,DL = row,column to start displaying
            BH = page number
            AL = sub function code:
                 0 = use attribute in BL; don't update cursor
                 1 = use attribute in BL; leave cursor at end of string
                 2 = string format: char,attr, char,attr...; don't update cursor
                 3 = string format: char,attr, char,attr...; do update cursor


Функции BIOS - INT 11H: проверка оборудования

INT 11H: проверка оборудования

INT 11H возвращает в AX биты, указывающие установленнное/активное оборудование.

Формат возращаемых данных описан в разделе "структуры".


Функции BIOS - INT 12H: размер используемой памяти

INT 12H: размер используемой памяти

INT 12H возвращает AX = число килобайт памяти в PC. Это то же значение, которое хранится в 0:413. Оно не включает переключаемую расширенную память (см. Спецификацию Expanded-памяти ). Оно также не включает "extended-память" с адресами выше 1 мегабайта. См. функции EMM и INT 15H для PC, это значение берется из переключателей. Машины PCjr, XT и большинство им подобных выполняют просмотр памяти во время POST , чтобы определить объем памяти. AT считывает свою CMOS-память , чтобы определить объем RAM.

Префикс программного сегмента (PSP) любой программы также содержит значение размера памяти; обращение к PSP:0002 - обычный способ определить, сколько памяти доступно программе. (DOS или иная управляющая программа может предоставить вашей программе не всю имеющуюся память). См. запуск и завершение программ .


Функции BIOS - INT 13H: дисковый ввод-вывод

INT 13H: дисковый ввод-вывод

Этот сервис предоставляет прямой доступ а адаптерам дискеты и твердого диска. Рекомендуется там, где это возможно, использовать INT 25H и INT 26H , чтобы предоставить драйверам устройств DOS выполнять всю низкоуровневую обработку. Разумеется, для таких операций, как форматирование диска или установка защиты от копирования, прерывание INT 13H может оказаться единственной альтернативой.

подфункции: 00H сброс контроллера 08H дать парам диска  10H проверить готовность
            01H дать статус       09H иниц табл парам   11H рекалибрация
            02H читать секторы    0aH длинное чтение    14H диагностика
            03H писать секторы    0bH длинная запись    15H дать тип диска
            04H верификация       0cH искать цилиндр    16H изменить статус
            05H форматир дорожку  0dH альтерн сброс     17H уст тип диска
AH  сервис
--- ----------------------------------------------------------------------------
00H Сброс устройства. вызывает рекалибрацию контроллера.
    если DL равен 80H или 81H, выполнен сброс контр тверд диска, иначе FDC.
--- ----------------------------------------------------------------------------
01H дать статус ошибки последней операции.
    вход: DL = диск.  DL < 80H = дискета;  DL > 7FH = твердый диск
   выход: AL содержит код ошибки диска (то же, что значение по адресу 0:0441)
--- ----------------------------------------------------------------------------
02H читать секторы
     вход: DL = номер диска (0=диск A...; 80H=тв.диск 0; 81H=тв.диск 1)
           DH = номер головки чтения/записи
           CH = номер дорожки (цилиндра)(0-n) =¬
           CL = номер сектора (1-n) ===========¦== См. замечание ниже.
           AL = число секторов (в сумме не больше чем один цилиндр)
           ES:BX => адрес буфера вызывающей программы
           0:0078 => таблица параметров дискеты (для гибких дисков)
           0:0104 => таблица параметров тв.диска (для твердых дисков)
   выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
          ES:BX буфер содержит данные, прочитанные с диска
          замечание: на сектор и цилиндр отводится соответственно 6 и 10 бит:
                 1 1 1 1 1 1
                +5-4-3-2-1-0-9-8-7-6-5-4-3-2-1-0+
            CX: ¦c c c c c c c c C c S s s s s s¦
                +-+-+-+-+-+-+-+-¦-+-+-+-+-+-+-+-+
                                +======> исп. как старшие биты номера цилиндра
--- ----------------------------------------------------------------------------
03H писать секторы
     вход: (аналогично подфункции 02H)
           ES:BX => данные, записываемые на диск.
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
--- ----------------------------------------------------------------------------
04H проверить секторы. проверяет CRC для указанных секторов на ошибки.
     вход: (аналогично подф. 02H. ES:BX лучше также предоставить)
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
--- ----------------------------------------------------------------------------
05H форматировать дорожку. данные на дорожке, если есть, разрушаются.
     вход: DL,DH,CH = диск,головка,дорожка (см. подф. 02H)
           ES:BX => дескрипторы секторов (требуется 512-байтовый буфер)
              дискета: 1 4-байтовый 'CHNS' (цилиндр,Головка,Nсектора,размер)
                       для каждого сектора на дорожке (т.е. 36 байт для 9-сек-
                       торных дорожек); номера секторов д.б. упорядочены.
                       'Z' - код размера сектора:  0=128; 1=256; 2=512; 3=1024
       ¦AT¦ Тв. диск: 1 2-байтовый 'FN' (флаг,Nсектора) для каждого сектора на
                      дорожке. последовательность полей 'N' определяет "коэффи-
                      циент прослаивания" ("interleave factor").
       ¦XT¦ Тв. диск: ES:BX не используется. Вместо этого AL содержит значение
                      "прослаивания" между 1 и 16 (10H).
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
           (тв. диск: 'F'-поля установлены в 80H, чтобы пометить плохие секторы)
--- ----------------------------------------------------------------------------
08H ¦AT¦  ¦XT¦ дать параметры диска. возвращает информацию об устройстве.
     вход: DL = диск
    выход: DL = число тв. дисков на первом контроллере
           DH = максимальный номер головки
           CH = максимальный номер цилиндра (младшие 8 бит)
           CL = максим. номер сектора (и старшие биты макс. номера цилиндра)
--- ----------------------------------------------------------------------------
09H ¦AT¦ инициализировать параметры диска. Сообщает BIOS о любом динамическом
    изменении таблиц параметров устройства.
     вход: векторы для INT 41H и INT 46H адресуют Табл. параметров тв. диска
           соответственно для устройств 0 и 1.
    замечание: ¦XT¦ должен указывать обе таблицы через вектор INT 40H.
--- ----------------------------------------------------------------------------
0aH ¦AT¦  ¦XT¦ чтение длинное: 512 байт + 4-байтоый ECC (код коррекции ошибок).
     вход: (как для подф. 02H)
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
           ES:BX => в буфере (данные сектора + 4 байта) * число секторов (из AL)
--- ----------------------------------------------------------------------------
0bH ¦AT¦  ¦XT¦ запись длинная. Пишет 512 байт + 4-байтовый ECC.
     вход: (как для подф. 02H)
           ES:BX => буфер содержит данные сектора + 4 байта на каждый сектор
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
--- ----------------------------------------------------------------------------
0cH ¦AT¦  ¦XT¦ Искать цилиндр. перемещает головку к нужной дорожке.
     вход: DL,DH,CH = диск,головка,дорожка (см. подф. 02H)
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
--- ----------------------------------------------------------------------------
0dH ¦AT¦  ¦XT¦ Альтернативный сброс устройства
     вход: DL = диск
--- ----------------------------------------------------------------------------
0eH ¦AT¦ читать буфер секторов
     вход: (как для подф. 02H)
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
--- ----------------------------------------------------------------------------
0fH ¦AT¦ писать буфер секторов
     вход: (как для подф. 02H)
    выход: Carry-флаг=1 при ошибке и код ошибки диска в AH.
--- ----------------------------------------------------------------------------
10H ¦AT¦  ¦XT¦ проверить готовность устройства
     вход: DL = диск
    выход: код ошибки диска (статус) в AH.
--- ----------------------------------------------------------------------------
11H ¦AT¦  ¦XT¦ Рекалибровать устройство
     вход: DL = диск
    выход: код ошибки диска (статус) в AH.
--- ----------------------------------------------------------------------------
12H ¦AT¦ Диагностика RAM контроллера
    выход: код ошибки диска (статус) в AH.
--- ----------------------------------------------------------------------------
13H ¦AT¦ Диагностика устройства
    выход: код ошибки диска (статус) в AH.
--- ----------------------------------------------------------------------------
14H ¦AT¦  ¦XT¦ Внутренняя диагностика контроллера
    выход: код ошибки диска (статус) в AH.
--- ----------------------------------------------------------------------------
15H ¦AT¦ читать тип диска (недоступна в XT BIOS)
     вход: DL = диск
    выход: AH = код устройства:
                0 = устройство DL отсутствует
                1 = дискета; логика замены диска отсутствует
                2 = дискета; логика замены диска доступна (большинство случаев)
                3 = твердый диск
--- ----------------------------------------------------------------------------
16H ¦AT¦ читать статус замены диска
    выход: AH = код статуса:
                0 = диск не был заменен
                6 = замена активна (открыта дисковая дверь);
                    DL = номер заменяемого диска
--- ----------------------------------------------------------------------------
17H ¦AT¦ установить тип дискеты (используется перед операцией форматирования)
     вход: DL = номер устройства диска (0 или 1)
           AL = тип носителя диска:
                0 = не используется
                1 = 360K дискета в 360K устройстве
                2 = 360K дискета в 1.2M устройстве
                3 = 1.2M дискета в 1.2M устройстве

Комментарии пользователей (всего 13)

ДиМко / 19 декабря 2009, 20:55:02

Клааассс!!! Спасибо ограмное!

ASoftware / 16 апреля 2009, 00:16:01

Кому надо коды ошибок?
00H последняя операция выполнена без ошибок
01H плохая команда: неверный запрос к контроллеру
02H плохая адресная марка
03H защита записи: попытка записи на защищенную дискету
04H ID сектора запорчен или не найден.
05H ошибка сброса -- _AT_
08H сбой DMA
09H перекрытие DMA: попытка записи через 64K-байтовую границу.
0bH встретился флаг плохой дорожки -- _AT_
10H сбой CRC: несовпадение контрольной суммы данных.
11H данные исправлены; исправимая ошибка; исправлено алгоритмом ECC -- _AT_
20H сбой контроллера
40H неудачный поиск. Запрошенная дорожка не найдена
80H Таймаут. Устройство не ответило
0bbH неопределенная ошибка -- _AT_
0ffH сбой операции опроса (sense) -- _AT_
Примечание.
_AT_ ...... обозначает IBM AT или совместимый; базируется на 80286 CPU
_XT_ ...... обозначает XT (обычно ссылается на отличия в BIOS твердого диска)

Кстати, не уверен, но 06H - должно быть отсутствует дискета.

Robotex / 23 октября 2008, 00:41:38

А где взять расшифровку кодов ошибок?

vov4ik / 21 января 2006, 04:02:13

Статейка руль!!! Афтару + балл за изложенное :))

Mikae / 07 января 2006, 15:35:55

2snowk@t:

Из BIOSа, без использования расширенных ф-ий не возможно адресовать более 8 ГБ.

Dizor / 28 октября 2005, 22:54:39

Полезная публикация.
Но я нашел в и-нет чуть более подробную информацию по данным функциям: http://www.clipx.net/ng/progref/ng5580e.php
Правда она на ангийском.

kahili / 02 сентября 2005, 23:44:32

смотря где искать=))

snowk@t / 15 апреля 2005, 17:50:50

на счет функции 08Н....получается что если у меня винт на 40Гб, максимум что она определит, так это ~8,5 Гб?

ghiwi / 01 апреля 2005, 16:32:18

7H ¦AT¦ установить тип
  дискеты (используется перед операцией форматирования)
вход: DL = номер устройства диска (0 или 1)
AL = тип носителя диска:
0 = не используется
1 = 360K дискета в 360K устройстве
2 = 360K дискета в 1.2M устройстве
3 = 1.2M дискета в 1.2M устройстве

GraZy / 28 марта 2005, 21:55:20

Улет!Спасибо автору....долго искал...


Функции BIOS - INT 14H: ввод-вывод через последовательный порт

INT 14H: ввод-вывод через последовательный порт

Эти функции BIOS предоставляют доступ к двум портам RS-232. Начиная с 0:0400, хранятся базовые адреса до 4-х последовательных портов, однако POST проверяет и инициализирует лишь два первых порта.

AH  сервис
--- ----------------------------------------------------------------------------
00H инициализировать коммуникационный порт
     вход: DX = номер порта (0-1)
           AL = битовые флаги параметра инициализации:
           +-7-T-6-T-5-T-4-T-3--T-2--T-1-T-0-+
           ¦ -- бод -- ¦четность¦стоп¦длина  ¦
           +---+---+---+---+----+-+--+---+---+
            +====+====+  +=+=+    ¦   +===¦==> длина слова
                 ¦         ¦      ¦           10=7 бит; 11=8 бит
                 ¦         ¦      +=========> стоп-бит: 0=1; 1=2;
                 ¦         +================> код четности
                 ¦                            x0=нет; 01=нечет; 11=чет
                 +==========================> бод:       000=110; 100=1200
                                                         001=150; 101=2400
                                                         010=300; 110=4800
                                                         011=600; 111=9600
    выход: AH = статус коммуникаций (см. ниже)
--- ----------------------------------------------------------------------------
01H послать символ через выбранный порт RS-232
     вход: DX = номер порта (0-1)
           AL = посылаемый символ
    выход: AL сохранен.
           если установлен бит 7 в AH, то произошла ошибка, и
              AH (биты 6-0) = статус линии связи (см. AH ниже)
--- ----------------------------------------------------------------------------
02H получить символ через выбранный порт RS-232
     вход: DX = номер порта (0-1)
    выход: AL = полученный символ
           AH ненулевой, если произошла ошибка
--- ----------------------------------------------------------------------------
03H дать статус порта связи
     вход: DX = номер порта (0-1)
    выход: AX = статус порта связи
           AH = статус линии              AL = статус модема
           ------------------------------ ------------------------------------
           bit 7: timeout                 bit 7: received line detect signal
           bit 6: trans shift reg empty   bit 6: ring indicator
           bit 5: trans holding reg empty bit 5: data set ready
           bit 4: break detect            bit 4: clear to send
           bit 3: framing error           bit 3: delta recv line signal detect
           bit 2: parity error            bit 2: trailing edge ring detector
           bit 1: overrun error           bit 1: delta data set ready
           bit 0: data ready status       bit 0: delta clear to send


Функции BIOS -

INT 15H: расширенный сервис AT

INT 15H обрабатывает специфические функции AT

ПодФнк: 00H Cass motor ON    80H Device Open        86H Wait
        01H Cass motor OFF   81H Device Close       87H Move Extended Mem Block
        02H Read cassette    82H Program terminate  88H Get Extended Mem Size
        03H Write cassette   83H Event wait         89H Switch to Virtual Mode
                             84H Joystick           90H Device Busy Loop
                             85H SysReq key         91H Finish Interrupt
замечание: Кассетные подфункции опущены для краткости (мне не нужны, а вам?)
AH  сервис
--- ----------------------------------------------------------------------------
80H открыть устр. возвращает, ничего не делая. См. подфункции 90H и 91H.
     вход: BX = ID устройства; CX = ID процесса
--- ----------------------------------------------------------------------------
81H Закрыть устр. возвращает, ничего не делая. См. подфункции 90H и 91H.
     вход: BX = ID устройства; CX = ID процесса
--- ----------------------------------------------------------------------------
82H завершить программу устройства. Ничего не делает. См. 90H и 91H.
     вход: BX = ID устройства
--- ----------------------------------------------------------------------------
83H Ждать события. Запустить таймер и установить флаг по истечении интервала.
     вход: AL = код подфункции:
           AL = 0: уст. интервал (и запустить таймер)
                   ES:BX = адрес пользовательского байта. бит 7 в этом байте
                           будет включен по истечении интервала.
                   CX,DX = длина интервала в микросекундах (CX - старшая часть)
           AL = 1: отменить ожидание события.
--- ----------------------------------------------------------------------------
84H Обеспечение джойстика.
     вход: DX = код подфункции:
           DX = 0: читать текущие переключатели
                   возврат: AL = значения переключателей (биты 7-4)
           DX = 1: читать входы X,Y джойстика
                   возврат: AX = джойстик 'A', значение X (горизонталь)
                            AX = джойстик 'A', значение Y (вертикаль)
                            AX = джойстик 'B', значение X (горизонталь)
                            AX = джойстик 'B', значение Y (вертикаль)
--- ----------------------------------------------------------------------------
85H клавиша SysReq. Эта функция ничего не делает. вызывается прерыванием
     INT 09H при нажатии и отпускании клавиши SysReq. Идея состоит в том, чтобы
     операционная система перехватывала INT 15H и выдавала подфункцию 85H,
     чтобы отслеживать состояние (нажата или отпущена) клавиши SysReq.
     вход: AL = 0: SysReq нажата ('make')
           AL = 1: SysReq отпущена ('break')
--- ----------------------------------------------------------------------------
86H Ждать. Циклит с разрешенными прерываниями до истечения интервала времени.
     вход: CX,DX = сколько микросекунд ждать до возврата к пользователю
--- ----------------------------------------------------------------------------
87H Переслать блок extended-памяти. перемещает блок памяти в extended-память и
     из нее (RAM выше 1 мегабайта на компьютерах  ¦286¦ ).
     вход: ES:SI => таблица глобальных дескрипторов (GDT) - см. ниже.
           CX = счетчик пересылаемых 16-битовых слов (максимум = 8000H = 32K)
    выход: Carry-флаг = 1 при ошибке.
           AH = 0 нет ошибки        AH = 2 прерывание по исключению
           AH = 1 ош. четности RAM  AH = 3 gate address line 20 failure
           структура GDT для подфункции 87H
             ES:[SI]+00H  Фиктивный дескриптор          (обнуляет пользователь)
             ES:[SI]+08H  дескриптор этой GDT           (обнуляет пользователь)
             ES:[SI]+10H  дескриптор блока источника    (см. ниже)
             ES:[SI]+18H  дескриптор блока назначения   (см. ниже)
             ES:[SI]+20H  кодовый сегмент для BIOS      (обнуляет пользователь)
             ES:[SI]+28H  стековый сегмент для BIOS     (обнуляет пользователь)
             ;---------- пример GDT для INT 15H, подфункции 87H
             INT_15_GDT  label byte
                         DB  8 dup(0)      ;фиктивный
                         DB  8 dup(0)      ;эта GDT
                         DW  0             ;source block "limit" value
             SRC_LO      DW  ?             ;24-битовый адрес
             SRC_HI      DB  ?
                         DB  93H           ;права доступа (read/write data seg)
                         DW  0             ;резерв
                         DW  0             ;target block "limit" value
             DEST_LO     DW  ?             ;24-битовый адрес
             DEST_HI     DB  ?
                         DB  93H           ;права доступа (read/write data seg)
                         DW  0             ;резерв
                         DB  8 dup(0)      ;code segment setup by BIOS
                         DB  8 dup(0)      ;stack segment setup by BIOS
             ;---------- конец примерной GDT
замечание: прерывания запрещаются в процессе перемещения данных, так что, если
           вы запускаете пачку конкурирующих процессов асинхронной передачи,
           избегайте перемещения больших объемов данных.   См. VDISK.SYS
--- ----------------------------------------------------------------------------
88H дать размер extended-памяти.
    выход: AX = число непрерывных 1K блоков сверх 1M (1024K)
--- ----------------------------------------------------------------------------
89H Войти в режим Protected (286 Virtual memory). это хитрая штука, если вы не
    знаете, что делаете. Лучше изучите эту функцию по листингу BIOS.
     вход: ES:SI => 8-элементная таблица глобальных дексрипторов (GDT) (ниже)
           BH = смещение в IDT начала первых 8 аппаратных прерываний
           BL = смещение в IDT начала вторых 8 аппаратных прерываний
    выход: AH = 0, если не было ошибок
           все сегментные регистры изменяются. AX и BP теряются.
           80286 входит в режим Protected без прямого выхода в режим Real.
           структура GDT для подфункции 89H
             ES:[SI]+00H  фиктивный дескриптор     (обнуляет пользователь)
             ES:[SI]+08H  дескриптор этой GDT      (инициализирует пользователь)
             ES:[SI]+10H  дескриптор для IDT       (инициализирует пользователь)
             ES:[SI]+18H  дескриптор для caller DS (инициализирует пользователь)
             ES:[SI]+20H  дескриптор для caller ES (инициализирует пользователь)
             ES:[SI]+28H  дескриптор для caller SS (инициализирует пользователь)
             ES:[SI]+30H  дескриптор для caller CS (инициализирует пользователь)
             ES:[SI]+38H  временный BIOS CS        (обнуляет пользователь)
--- ----------------------------------------------------------------------------
90H Цикл занятости устройства. Ничего не делает. Я полагаю, что, если ваши
     инициалы - MS или DR, вы можете перехватывать эту функцию и заставить
     ее что-то делать.
     вход: AL = код типа устройства
                00H = твердый диск
                01H = дискета
                02H = клавиатура
                80H = сеть
                      ES:BX => управляющий блок сети
                fdH = запуск мотора дискеты
                feH = принтер
--- ----------------------------------------------------------------------------
91H завершить прерывание. Ничего не делает. Идея здесь - предоставить механизм
     для обработчика устройства, чтобы проверять занятость устройства. когда
     обработчик завершил обработку запроса, он может использовать эту функцию,
     чтобы дать знать системе, что устройство свободно.
     вход: AL = код типа устройства (см. подфункцию 90H)
           AL = 00H - 7fH: последовательно используемые устройства
           AL = 80H - bfH: реентерабельные устройства (ES:BX => пакет данных)


Функции BIOS - INT 16H: сервис клавиатуры

INT 16H: сервис клавиатуры.

Это - интерфейс прикладного уровня с клавиатурой. Нажатия клавиш на самом деле обрабатываются асинхронно на заднем плане. когда клавиша получена от клавиатуры, она обрабатывается прерыванием INT 09H и помещается в циклическую очередь.

AH  сервис
--- ----------------------------------------------------------------------------
00H читать (ожидать) следующую нажатую клавишу
     выход: AL = ASCII символ (если AL=0, AH содержит расширенный код ASCII )
            AH = сканкод  или расширенный код ASCII
--- ----------------------------------------------------------------------------
01H проверить готовность символа (и показать его, если так)
     выход: ZF = 1 если символ не готов.
            ZF = 0 если символ готов.
                        AX = как для подфункции 00H (но символ здесь не
                             удаляется из очереди).
--- ----------------------------------------------------------------------------
02H читать состояние shift-клавиш. определить, какие shift-клавиши нажаты в
     данный момент, находится ли клавиатура в состоянии NumLock, и т.п.
     выход: AL = статус клавиатуры -- см. флаги клавиатуры

Vadik94 / 12 сентября 2009, 22:03:05

кто-нибудь что-то знает про функцию 10h прерывания 16h?
и есть ли другие функции этого прерывания и где их можно найти?


Функции BIOS -

INT 17H: поддержка принтера.

Эти функции предоставляют доступ к портам параллельных принтеров (LPT1 и т.д.) адреса портов принтеров хранятся, начиная с 0:0408. См. данные BIOS

AH  сервис
--- ----------------------------------------------------------------------------
00H Печатать символ
     вход: AL = ASCII символ. См. также: управляющие коды ASCII
           DX = номер принтера (0,1 или 2)
    выход: AH = 01H если символ не напечатан (ошибка таймаута)
                другие биты - как в подфункции 02H (флаги состояния)
--- ----------------------------------------------------------------------------
01H инициализировать порт принтера
     вход: DX = номер принтера (0,1 или 2)
    выход: AH = как в подфункции 02H (флаги состояния)
--- ----------------------------------------------------------------------------
02H дать статус принтера
     вход: DX = номер принтера (0,1 или 2)
    выход: AH = флаги состояния принтера
           г7T6T5T4T3T2T1T0¬
           ¦ ¦ ¦ ¦ ¦ ¦   ¦ ¦
           +++++++++++-+-++-
            ¦ ¦ ¦ ¦ ¦ +++ +=> таймаут      (AH & 01H)
            ¦ ¦ ¦ ¦ ¦  +====> (не используется)
            ¦ ¦ ¦ ¦ +=======> ошибка в/в   (AH & 08H)
            ¦ ¦ ¦ +=========> выбран       (AH & 10H) (00H означает офлайн)
            ¦ ¦ +===========> нет бумаги   (AH & 20H)
            ¦ +=============> подтверждение(AH & 40H) (40H = присоединен)
            +===============> не занят     (AH & 80H) 0 - означает занятость


Функции BIOS - INT 18H: ROM-BASIC

INT 18H: ROM-BASIC

Этот вектор содержит точку входа для интерпретатора ROM-BASIC, который установлен только на зарегистрированных компьютерах IBM. Клоны (родственники) не имеют BASIC в ROM-памяти и должны использовать отдельную программу, обычно GWBASIC. Если ROM-BIOS не может найти диск для загрузки, он берет этот вектор. это делает возможным для внешнего модуля ROM-Scan изменить этот вектор так, чтобы он указывал на него, вызывая его при сбое или отсутствии дисков.

Комментарии пользователей (всего 1)

ant-str / 02 апреля 2006, 09:43:57

Эта информация устарела много лет назад.

BIOS Boot Specification 1.01, 1996

Appendix D: Recommended Boot Sector Changes (Optional)
If O/S’s responded to the mechanism of passing the INT 13h drive number to the boot
sector as defined by the Plug and Play BIOS Specification, the BIOS could boot from
any INT 13h drive. Also, if a standard method of returning control to the BIOS upon
boot failure were established, the BIOS could try to boot from the next device. Here
are two recommended changes to the O/S boot sector code in order to enhance the
booting capabilities of the BIOS.
D.1 Use DL for Drive Number
Use the drive number passed in the DL register by the BIOS when control is
transferred to the boot sector for INT 13h accesses to load the O/S, instead of having
the drive number hard-coded. This would allow booting from drives other than just
00h (A:) and 80h (C:).
D.2 INT 18h on Boot Failure
If an O/S is either not present, or otherwise not able to load, execute an INT 18h
instruction so that control can be returned to the BIOS. Currently, hard drive boot
sectors do this, but floppy diskette boot sectors execute an INT 19h instead of INT
18h. The BIOS Boot Specification defines INT 18h as the recovery vector for failed
boot attempts.
Both of these solutions should be backward compatible with previous BIOS and O/S
versions.

Из этого следует, что int 18 используется для передачи управления BIOS загрузочным сектором в случае, если произошла ошибка при загрузке операционной системы.


Функции BIOS - INT 19H: начальный загрузчик (Bootstrap Loader)

INT 19H: начальный загрузчик (Bootstrap Loader)

Этот вектор рассматривается после POST , чтобы попытаться загрузить и выполнить какой-либо код "начального вызова" на дискете или твердом диске. Данные в секторе 1 дорожки 0 головки 0 дисковода 0 для первого откликнувшегося диска (дискеты или твердого диска) загружаются по абсолютному адресу 0000:7c00, и управление передается по этому адресу. если опрос всех дисков неудачен, управление передается на прерывание INT 18H .

На твердом диске, этот код в "корневом секторе" в действительности определяет активный раздел диска, а затем загружает и выполняет корневой сектор для этого раздела. это передает управление активной операционной системе диска.

Замечание:

Вы можете использовать этот сервис, чтобы перезагрузить DOS после изменения каких-либо значений в Списке оборудования или иных переменных BIOS (не забудьте установить по адресу 0:0472 значение 1234H). после перезагрузки DOS примет во внимание все ваши изменения.

Комментарии пользователей (всего 4)

ant-str / 02 апреля 2006, 09:50:57

Пояснение к предыдущему сообщению.
BIOS Boot Specification 1.01, 1996

ant-str / 02 апреля 2006, 09:49:19

Данная информация давно устарела.

Appendix D: Recommended Boot Sector Changes (Optional)
If O/S’s responded to the mechanism of passing the INT 13h drive number to the boot
sector as defined by the Plug and Play BIOS Specification, the BIOS could boot from
any INT 13h drive. Also, if a standard method of returning control to the BIOS upon
boot failure were established, the BIOS could try to boot from the next device. Here
are two recommended changes to the O/S boot sector code in order to enhance the
booting capabilities of the BIOS.
D.1 Use DL for Drive Number
Use the drive number passed in the DL register by the BIOS when control is
transferred to the boot sector for INT 13h accesses to load the O/S, instead of having
the drive number hard-coded. This would allow booting from drives other than just
00h (A:) and 80h (C:).
D.2 INT 18h on Boot Failure
If an O/S is either not present, or otherwise not able to load, execute an INT 18h
instruction so that control can be returned to the BIOS. Currently, hard drive boot
sectors do this, but floppy diskette boot sectors execute an INT 19h instead of INT
18h. The BIOS Boot Specification defines INT 18h as the recovery vector for failed
boot attempts.
Both of these solutions should be backward compatible with previous BIOS and O/S
versions.

Это значит, что int 19 используется только в загрузочных секторах флоппи дисков. Новые программы должны использовать int 18 для передачи управления в BIOS при возникновении ошибки во время загрузки операционной системы.

Denri / 02 октября 2004, 22:04:09

Перезагрузку "надёжнее" выполнять с помощью инструкции JMP FFFF:0000 (EA 00 00 FF FF), т. к. INT 19H не восстанавливает векторы прерываний, если те были изменены, и могут возникать разные "спецдефекты", вроде тех, что описал Araik.

Araik / 04 сентября 2004, 14:33:22

Проблема: В DOS Win9x когда система вызвана из флоппи
при использовании INT 19h происходит нормальная "горячая"
перезагрузка, а когда система вызвана из С: ,после попитки загрузи комп зависает.
Вопрос: Как можно решить эту проблему?


Функции BIOS - INT 1aH: ввод-вывод для времени

INT 1aH: ввод-вывод для времени.

Этот сервис предоставляет доступ к системным часам. PC BIOS работает со "счетчиком тиков" - числом 55-мс интервалов, прошедших с момента включения или сброса PC. AT BIOS предоставляет также доступ к значениям часов реального времени, которые постоянно обновляются независимо от работы процессора и хранятся в CMOS-памяти компьютера AT.

AH  сервис
--- ----------------------------------------------------------------------------
00H читать часы (счетчик тиков)
    выход: CX,DX = счетчик тиков с момента сброса. CX - старшая часть значения.
           AL = 0, если таймер не переполнялся за 24 часа с момента сброса.
      замечание: часы обновляются каждые 1193180/65536 (ў 18.2) тиков в секунду.
                 тиков в секунде   ў 18
                 тиков в минуте    ў 1092
                 тиков в часе      ў 65543
                 тиков в сутках    ў 1573040
--- ----------------------------------------------------------------------------
01H установить часы (счетчик тиков)
     вход: CX,DX = счетчик тиков. CX - старшая часть значения.
--- ----------------------------------------------------------------------------
02H ¦AT¦ читать время из "постоянных" (CMOS) часов реального времени
    выход: CH = часы в коде BCD   (пример: CX = 1243H = 12:43)
           CL = минуты в коде BCD
           DH = секунды в коде BCD
    выход: CF = 1, если часы не работают
--- ----------------------------------------------------------------------------
03H ¦AT¦ установить время на "постоянных" (CMOS) часах реального времени
     вход: CH,CL = часы,минуты в коде BCD
           DH    = секунды в коде BCD
           DL = 1 для опции "единиц светового дня"
--- ----------------------------------------------------------------------------
04H ¦AT¦ читать дату из "постоянных" (CMOS) часов реального времени
    выход: CH = столетие в коде BCD (пример: CX = 1987H = 1987)
           CL = год в коде BCD
           DH = месяц в коде BCD   (пример: DX = 0312H = 12-е марта)
           DL = день в коде BCD
    выход: CF = 1, если часы не работают
--- ----------------------------------------------------------------------------
05H ¦AT¦ установить дату на "постоянных" (CMOS) часах реального времени
     вход: CH,CL = столетие,год в коде BCD
           DH,DL = месяц, день в коде BCD
--- ----------------------------------------------------------------------------
06H ¦AT¦ установить сигнал часов реального времени. В указанное время вызывается
     пользовательская программа по вектору прерывания INT 4aH. Лишь один сигнал
     может быть активен в каждый момент времени.
     вход: CH,CL = часы,минуты в коде BCD
           DH    = секунды в коде BCD
    выход: CF = 1, если часы не работают или сигнал уже активен
--- ----------------------------------------------------------------------------
07H ¦AT¦ сбросить сигнал часов реального времени. это позволяет вам отменить
     один сигнал перед установкой другого.


Функции BIOS - INT 1bH: прерывание с клавиатуры.

INT 1bH: прерывание с клавиатуры.

Этот вектор (0:006c) берется, когда BIOS распознает нажатие клавиши Ctrl-Break. INT 1bH первоначально указывает на IRET, но DOS устанавливает его на локальную программу, которая взводит внутренний флаг DOS. DOS время от времени проверяет этот флаг и действует в соответствии с действующим режимом обработки прерываний.

См. DOS Fn 33H и INT 23H о том, как DOS обрабатывает Ctrl-Break. Флаг в области данных BIOS (0:0471) взводится при первом распознавании нажатия Ctrl-Break, но он никогда не сбрасывается, если вы не сделаете это сами. Вы можете использовать этот флаг в родительском процессе, чтобы определить, был ли порожденный процесс снят через Ctrl-Break.


Функции BIOS - INT 1cH: пользовательское прерывание по таймеру

INT 1cH: пользовательское прерывание по таймеру

Этот вектор (0:0070) BIOS берет по каждому тику аппаратных часов (каждые 55 миллисекунд; приблизительно 18.2 раз в секунду). первоначально он указывает на IRET, но может быть изменен пользовательской программой, чтобы адресовать фоновую программу пользователя, базирующуюся на таймере.

Поскольку программа INT 1cH выполняется во время низкоуровневого аппаратного прерывания, вы должны помнить, что система еще не сбросила контроллер прерываний и потому другие аппаратные прерывания, в том числе прерывание от клавиатуры, не будут происходить при работе INT 1cH (т.е. вы не получите ввода пользователя). Большинство popup-программ предпочитают перехватывать вектор INT 08H , вызывать первоначальный вектор, а затем уже выполнять операции, зависящие от времени, после того как BIOS закончит свою обслугу.


Функции BIOS - INT 1dH: указатель видеопараметров

INT 1dH: указатель видеопараметров.

Этот вектор (0:0074) указывает на совокупность видео параметров, используемых прерыванием INT 10H для установки регистров видеоконтроллера и некоторых значений данных BIOS при инициализации режима видео.

Можно создать RAM-резидентную версию этой таблицы и модифицировать параметры, чтобы изменить работу некоторых экранных режимов. например, таким способом команда DOS "Mode" сдвигает экран влево или вправо.

Комментарии пользователей (всего 2)

Rockie / 20 июля 2005, 06:59:21

Я похоже в выше сказанном полный ламер =) Например в досовском Турбо Си (3.0) на адаптере VGA выдается максимальное разрешение 640 на 480. Можно сделать 1024*768?
С уважением.


Функции BIOS - INT 1eH: указатель параметров дискеты

INT 1eH: указатель параметров дискеты.

Этот вектор (0:0078) указывает на таблицу параметров дискеты, которую сервисная служба BIOS INT 13H использует для различных операций с дискетами.

В эту таблицу входят такие значения, как "head-settle time" и "step rate time", оказывающие огромное влияние на скорость операций ввода-вывода дискеты. Можно создать RAM-резидентную версию этой таблицы и модифицировать некоторые ее параметры, чтобы изменить отдельные детали операций с дискетами. DOS создает модифицированную версию этой таблицы для улучшения производительности дискет. Странно, но DOS восстанавливает нормальные (более медленные) значения, когда возвращает управление прикладной программе.


Функции BIOS - INT 1fH: указатель графических символов

INT 1fH: указатель графических символов.

Этот вектор (0:007c) указывает на таблицу, определяющую изображения старших 128 символов (коды ASCII 128-255). Ее использует ROM-BIOS, когда выводит на экран символы в графическом (с битовой разверткой) режиме.

При запуске системы этот указатель устанавливается на F000:0000, так что старшие 128 символов в графическом режиме выдаются как случайный "мусор". команда DOS 3.x "GrafTabl" может использоваться для загрузки таблицы старших 128 символов и соответствующей переустановки данного вектора.

Вы можете создать вашу собственную RAM-резидентную таблицу, например, чтобы предоставить курсив для графики. таблица состоит из 128 групп по 8 байт в группе. Каждый байт представляет 8 точек по горизонтали, причем первый байт отвечает верхней строке точек, составляющих изображение символа. например, определение символа "Л" могло бы быть следующим:

                         г7+6+5+4+3+2+1+0¬
 смещение_в_таблице + 0: ¦  $ $ $ $ $ $  ¦ = 01111110 = 7e hex =¬
 смещение_в_таблице + 1: ¦    $ $ $ $    ¦ = 00111100 = 3c hex  ¦
 смещение_в_таблице + 2: ¦  $ $   $ $    ¦ = 01101100 = 6c hex  ¦
 смещение_в_таблице + 3: ¦  $ $   $ $    ¦ = 01101100 = 6c hex  ¦=> =¬
 смещение_в_таблице + 4: ¦  $ $   $ $    ¦ = 01101100 = 6c hex  ¦    ¦
 смещение_в_таблице + 5: ¦  $ $   $ $    ¦ = 01101100 = 6c hex  ¦    ¦
 смещение_в_таблице + 6: ¦$ $     $ $ $  ¦ = 11001110 = ce hex  ¦    ¦
 смещение_в_таблице + 7: ¦               ¦ = 00000000 = 00 hex =-    ¦
                         +-+-+-+-+-+-+-+-+                           ¦
                                                +====================+
                                                ¦
                                +===============¦=============+
8-байтовая последовательность:  7еH,3cH,6cH,6cH,6cH,6cH,ceH,00H стояла бы в
таблице по смещению, соответствующему символу "Л". так как код ASCII буквы 'Л'
равен 139, а таблица начинается для символа с кодом 128, это будет 12-я группа
из 8 байт (смещение - 88 байт от начала таблицы).

замечание:

Младшие 128 символов хранятся в ROM-таблице по адресу f000:fa6e. Это не указано в документации, но, похоже, этот адрес остается постоянным во всех IBM-версиях ROM. этот адрес жестко закодирован в кодах программы INT 10H, так что вы не можете использовать свою таблицу для младших 128 символов (если у вас не EGA , который позволяет переопределять весь набор символов).


Функции DOS - INT 20H: завершить программу

INT 20H: завершить программу.

Это прерывание используется для выхода из программы и возврата управления родительскому процессу (обычно интерпретатору команд DOS - COMMAND.COM). Оно восстанавливает значения управляющих векторов INT 22H INT 23H INT 24H Оно также сбрасывает все файловые буфера (если длина файла изменилась, то файл должен быть предварительно закрыт).

Важно:

Регистр CS должен содержать значение PSP завершающегося процесса. Если ваш CS не равен PSP, вы можете выдать JMP или RET на PSP:0000.

Рекомендуется использовать функцию 4cH Terminate, чтобы избежать трудностей, связанных с неравенством CS и PSP. Она позволяет также задать код выхода. Программы COM-формата обычно выполняются при CS=PSP, так что им можно выдавать INT 20H в любой момент. EXE-программы могут выдавать FAR JMP или FAR RET, чтобы передать управление на PSP:0000, где содержится инструкция INT 20H.


Функции DOS - INT 21H: сервис DOS

INT 21H: сервис DOS

Это прерывание служит главным входом большинства функций DOS.

Программа, запрашивающая сервис DOS, должна подготовить всю необходимую информацию в регистрах и управляющих блоках, указать в регистре AH номер желаемой функции DOS и затем вызвать прерывание INT 21H.

  • Функция DOS 00H: завершить программу
  • Функция DOS 01H: ввод с клавиатуры
  • Функция DOS 02H: вывод на дисплей
  • Функция DOS 03H: ввод AUX
  • Функция DOS 04H: вывод AUX
  • Функция DOS 05H: вывод на принтер
  • Функция DOS 06H: Обмен с консолью
  • Функция DOS 07H: Нефильтрующий консольный ввод без эха
  • Функция DOS 08H: Консольный ввод без эха
  • Функция DOS 09H: Выдать строку
  • Функция DOS 0aH: буферизованный ввод строки
  • Функция DOS 0bH: проверить статус ввода
  • Функция DOS 0cH: ввод с очисткой
  • Функция DOS 0dH: Сбросить диск
  • Функция DOS 0eH: Выбрать умалчиваемый диск DOS
  • Функция DOS 0fH: открыть файл через FCB
  • Функция DOS 10H: Закрыть файл через FCB
  • Функция DOS 11H: Найти 1-й совпадающий файл через FCB
  • Функция DOS 12H: Найти следующий совпадающий файл через FCB
  • Функция DOS 13H: Удалить файл через FCB
  • Функция DOS 14H: читать последовательный файл через FCB
  • Функция DOS 15H: писать последовательный файл через FCB
  • Функция DOS 16H: создать файл через FCB
  • Функция DOS 17H: Переименовать файл через FCB
  • Функция DOS 19H: дать умалчиваемый диск DOS
  • Функция DOS 1aH: установить адрес DTA
  • Функция DOS 1bH: дать информацию FAT (текущий диск)
  • Функция DOS 1cH: дать информацию FAT (любой диск)
  • Функция DOS 21H: читать запись произвольного файла
  • Функция DOS 22H: писать запись произвольного файла
  • Функция DOS 23H: дать размер файла через FCB
  • Функция DOS 24H: установить адрес блока произвольного файла
  • Функция DOS 25H: установить вектор прерывания
  • Функция DOS 26H: создать префикс программного сегмента
  • Функция DOS 27H: читать блок произвольного файла
  • Функция DOS 28H: писать блок произвольного файла
  • Функция DOS 29H: Разобрать имя файла
  • Функция DOS 2aH: дать дату DOS
  • Функция DOS 2bH: установить дату DOS
  • Функция DOS 2cH: дать время DOS
  • Функция DOS 2dH: установить время DOS
  • Функция DOS 2eH: установить/сбросить переключатель верификации
  • Функция DOS 2fH: дать текущий DTA
  • Функция DOS 30H: дать номер версии DOS
  • Функция DOS 31H: завершиться и остаться резидентным -- KEEP
  • Функция DOS 32H: дать дисковую информацию DOS (недокументировано)
  • Функция DOS 33H: установить/опросить уровень контроля прерывания DOS
  • Функция DOS 34H: адрес статуса реентерабельности DOS
  • Функция DOS 35H: дать вектор прерывания
  • Функция DOS 36H: дать свободную память диска
  • Функция DOS 37H: установить/опросить символ-переключатель (недокументировано)
  • Функция DOS 38H: дать/установить информацию страны
  • Функция DOS 39H: создать новое оглавление -- MKDIR
  • Функция DOS 3aH: Удалить оглавление -- RMDIR
  • Функция DOS 3bH: установить умалчиваемое оглавление DOS -- CHDIR
  • Функция DOS 3cH: создать описатель файла
  • Функция DOS 3dH: открыть описатель файла
  • Функция DOS 3eH: Закрыть описатель файла
  • Функция DOS 3fH: читать файл через описатель
  • Функция DOS 40H: писать в файл через описатель
  • Функция DOS 41H: Удалить файл
  • Функция DOS 42H: установить указатель файла -- LSEEK
  • Функция Функция DOS 43H: установить/опросить атрибут файла -- CHMOD
  • Функция DOS 44H: управление вводом-выводом устройства -- IOCTL
  • Функция DOS 45H: Дублировать описатель файла -- DUP
  • Функция DOS 46H: переназначить описатель -- FORCDUP
  • Функция DOS 47H: дать умалчиваемое оглавление DOS
  • Функция DOS 48H: распределить память (дать размер памяти)
  • Функция DOS 49H: Освободить блок распределенной памяти
  • Функция DOS 4aH: Сжать или расширить блок памяти
  • Функция DOS 4bH: выполнить или загрузить программу -- EXEC
  • Функция DOS 4cH: завершить программу -- EXIT
  • Функция DOS 4dH: дать код выхода программы -- WAIT
  • Функция DOS 4eH: Найти 1-й совпадающий файл
  • Функция DOS 4fH: Найти следующий совпадающий файл
  • Функция DOS 54H: дать переключатель верификации DOS
  • Функция DOS 56H: Переименовать/переместить файл
  • Функция DOS 57H: установить/опросить время/дату файла
  • Функция DOS 59H: дать расширенную информацию об ошибке
  • Функция DOS 5aH: создать уникальный временный файл
  • Функция DOS 5bH: создать новый файл
  • Функция DOS 5cH: блокировать/разблокировать доступ к файлу
  • Функция DOS 5eH: различные сетевые функции
  • Функция DOS 5fH: переназначение устройств в сети
  • Функция DOS 62H: дать адрес префикса программного сегмента


Функции DOS - INT 25H/26H: Прямая дисковая операция чтения/записи

INT 25H/26H: Прямая дисковая операция чтения/записи

  • AL = номер диска (0=A, 1=B, и т.д.)
  • CX = счетчик считываемых или записываемых секторов
  • DX = начальный сектор (логический номер сектора DOS)
  • DS:BX = адрес данных (исходный или целевой буфер)

Выход

  • Выход
  • AX = код ошибки, если взведен флаг переноса (CF=1) (см. ниже)
  • значения всех регистров портятся, за исключением DS,ES,SS,SP ВАЖНО: эти функции оставляют одно лишнее слово в стеке

Этот сервис DOS предоставляет прямой доступ к любому сектору диска, доступному через DOS-BIOS или устанавливаемые драйверы устройств.

  • INT 25H читает секторы
  • INT 26H записывает секторы

Логические секторы DOS начинаются с корневого сектора . первый сектор в разделе DOS - это логический сектор 0. номера логических секторов возрастают сначала для каждого сектора на цилиндре, затем по каждой головке, и наконец по каждому цилиндру на устройстве.

Заметьте, что Главная корневая запись и любые другие секторы вне раздела DOS недоступны через этот сервис. прерывание INT 13H - это единственный сервис, который предоставляет полный доступ к любой части твердого диска.

Ошибки

Ошибки, возникающие в процессе INT 25H/26H, НЕ обрабатываются обработчиком кртических ошибок INT 24H . при выходе из INT 25H/26H, DOS-BIOS взводит флаг переноса (CF=1), когда встречается ошибка. Если установлен флаг CF:

  • AL = ошибка устройства (0-0cH) - аналогично битам 0-7 в DI для INT 24H - это
  • AL = один из кодов ошибок 13H-1fH (без 13H) в списке кодов ошибок DOS
  • AH = 80H = attachment failed to respond
  • AH = 40H = ошибка операции поиска на диске
  • AH = 08H = неверная контрольная сумма (CRC) при чтении дискеты
  • AH = 04H = запрошенный сектор не найден
  • AH = 03H = попытка записи на защищенную от записи дискету
  • AH = 02H = ошибка, отличная от перечисленных выше

Пример

Участок программы, читающий корневой сектор дискеты:

            mov     al,0          ;выбрать диск A
            mov     dx,0          ;выбрать корневой сектор DOS и BPB
            mov     cx,1          ;читать один сектор ...
            lea     bx,my_buf     ; ... в буфер по адресу DS:BX
            int     25H
            pop     dx            ;удалить лишнее слово из стека
            jnc     no_err
            ...и т.д.             ;обработать любую ошибку диска (код в AX)
   no_err:  ...и т.д.             ;продолжить (ошибок нет)

Замечание:

Не следует предполагать, что сектор содержит ровно 512 байт. Используйте функции 1cH или 32H либо прочитайте корневой сектор , чтобы определить истинный размер секторов.

32 мегабайта?

Утверждается, что DOS поддерживает максимальный объем диска в 32 Мб, но, строго говоря, это неправда. для стандартных драйверов устройств размер сектора равен 512K. Очвидно, что, поскольку наибольший номер сектора, который можно поместить в DX для INT 25H/26H, равен 65535, максимальный размер диска получается равным 32767K, или 32M.

Однако не-IBM'овские драйверы (или будущие драйверы IBM) могут поддерживать размер сектора, больший 512 байт. Поэтому для размера диска нет практических ограничений. Даже для сегодняшних драйверов, 32-мегабайтный максимум относится лишь к единственному разделу DOS.


Функции DOS - INT 27H: завершиться, но остаться резидентным

INT 27H: завершиться, но остаться резидентным

Вход:

  • DX = адрес первого байта за резидентным участком программы (DX интерпретируется как смещение от PSP (DS/ES при запуске)

Выход:

  • нет

Возвращает управление DOS, оставляя часть памяти распределенной, так что последующие программы не будут перекрывать программный код или данные в этой памяти.

INT 27H - это традиционный метод установки программ обслуживания прерываний и пользовательских таблиц данных. Функция 31H (KEEP) - гибкая альтернатива этому.

INT 27H (и все типы выходов в DOS) восстанавливает векторы INT 22H-24H из PSP завершающейся программы. Поэтому этот сервис нельзя использовать для установки постоянного обоаботчика критических ошибок или обработчика Ctrl-Break.


Функции DOS - INT 28H: DOS Квант времени DOS (нет в документации)

INT 28H: DOS Квант времени DOS (нет в документации)

Зто НЕДОКУМЕНТИРОВАННОЕ прерывание DOS использует, когда ждет нажатия клавиши, а также перед вызовом некоторых функций DOS с номерами до 0ch включительно. PRINT (спулер DOS) перехватывает этот вектор, чтобы найти квант времени для чтения файлов и вывода на принтер. это прерыание используется также различными резидентными popup-программами (TSR).

Обычно TSR использует INT 28H как одну из нескольких своих точек входа. То есть, TSR перехватывает нажатия клавиш и/или другие триггерные события, и устанавливает флаг, если требуется активизация. затем, в процессе обработки INT 28H, TSR вызывает исходный обработчик этого прерывания, и, если флаг запроса установлен, активизирует свой код.

ВАЖНО:

Popup-программа НЕ должна использовать функций DOS с номерами вплоть до 0cH, пока она выполняется внутри INT 28H.


Функции DOS - INT 2eH: выполнить команду DOS (нет в документации)

INT 2eH: выполнить команду DOS (нет в документации)

Вход:

  • DS:SI = адрес выполняемой команды DOS в форме "Lstring" (должна быть доступная память для загрузки программы)

Выход:

  • SS,SP = разрушены
  • ?? = не ясно, как получить статус выполненного запроса

Это НЕДОКУМЕНТИРОВАННОЕ прерывание выполняет команду DOS, как если бы эта команда была введена в ответ на подсказку DOS.

При входе DS:SI указывает на строку, в первом байте которой содержится длина строки, а в последнем байте - 0dH (символ 0dH не входит в подсчет длины).

    DB   0fH, "set PROMPT=$p$g", 0dH  ; ** строка длиной 0fH байт **

Этот пример иллюстрирует основное использование этого сервиса -- он позволяет устанавливать значения в главном (корневом) окружении DOS. В любых других случаях предпочтительнее функция DOS 4bH (например, выполнить COMMAND.COM, передав как параметр строку "/c dos_cmd"), поскольку она полностью документирована.

Замечание:

Не забывайте сначала сжать текущий MCB посредством функции DOS 4aH. Оставляйте МНОГО памяти для стека -- DOS буквально пожирает стек. SS и SP должны быть сохранены перед вызовом и восстановлены после. Этот сервис покрыт тайной. Он явно не используется ни одной программой DOS, включая COMMAND.COM. Из-за этой загадочности мы рекомендуем не использовать его.


Функции DOS -

INT 2fH: Мультиплексное прерывание

Вход:

  • AH = номер мультиплексного процесса
    • 01H = резидентная порция команды DOS 'PRINT'
    • 02H = резидентная порция команды DOS 'ASSIGN'
    • 10H = резидентная порция команды DOS 'SHARE'
    • 03H-7fH (зарезервировано)
    • 80H-0ffH (доступно для других процессов)
  • AL = номер подфункции
  • прочие = зависят от подфункций и конкретных мультиплексных процессов

Выход:

  • AX = код ошибки, если взведен флаг CF (для процессов DOS)
  • AL = статус установки (для процессов DOS)
    • 00H = не установлен. можно устанавливать
    • 01H = не установлен. Нельзя устанавливать
    • ffH = установлен

Этот вектор (0000:00bc) предоставляет средства управления процессами, доступные всей системе из любого приложения.

Каждый процесс должен включить себя в цепочку прерываний с этим кодом, и каждый процесс в цепочке должен проверять AH на свой мультиплексный номер процесса. Если запрос относится к другому процессу, активный процесс должен передать управление по первоначальному адресу прерывания 2fH (по адресу, который был в векторе 0:00bc перед тем, как текущий процесс установил себя).

Версии DOS:

INT 2fH не определено для более ранних версий, чем DOS 3.0 В DOS 3.0, INT 2fH определено ТОЛЬКО для PRINT, и значение AH (которое определяет номер процесса) не определено. В DOS 3.2, этот вектор определен так, как описано выше.

Print Spooler:

  • AH=1 (или AH=что угодно для DOS 2.x) это - интерфейс, определяемый для фоновой печати (печатного спулинга) после выполнения команды DOS 'PRINT'.
  • AL - номер подфункции (0-5). все подфункции могут возвращать ошибки (см. ниже).
    • AL = 0: опросить статус установки процесса
      • Выход:
      • AL = 00H = не установлен, можно устанавливать
      • AL = 01H = не установлен, нельзя устанавливать
      • AL = ffH = установлен
    • AL = 1: направить файл к спулеру
      • DS:DX => направляемый пакет
      • смещение 0 =уровень (всегда 0 для DOS 3.0, 3.1 и 3.2)
      • смещение 1 =DWORD адрес (смещение,сегмент) строки ASCIIZ, содержащей диск, путь и имя файла, направляемого в очередь печати (глобальные - обобщенные - имена НЕ допускаются)
    • AL = 2: снять выбранные файлы
      • DS:DX => строка ASCIIZ с именем удаляемого из очереди файла (глобальные символы допускаются в имени)
    • AL = 3: Снять все файлы (удалить все файлы из очереди и остановить печать)
    • AL = 4: статус. возвращает счетчик ошибок и задерживает очередь для изучения.

используйте подфункцию 5, чтобы освободить очередь.

Возвращает: DS:SI => блок описания файла в очереди. Один или несколько блоков с ASCIIZ-именами файлов. Конец блока отмечается именем, начинающимся с 00H.

DX = счетчик последовательных ошибок, встретившихся при попытке вывода последнего символа.

    • AL = 5: конец статуса. Освобождает очередь для продолжения печати.
    • AL = 0f8H-0ffH: (резервируется для DOS)

Ошибки спулера:

Если установлен флаг CF, то AX содержит код ошибки:

      • AX = 1 - неверный номер функции
      • AX = 2 - файл не найден
      • AX = 3 - Путь не найден
      • AX = 4 - Слишком много файлов (нет доступных описателей)
      • AX = 5 - доступ отвергнут
      • AX = 6 - неверный описатель (handle)
      • AX = 8 - переполнение очереди
      • AX = 9 - Занято
      • AX = 0Ch - Путь и имя файла превышают 64 символа
      • AX = 0Fh - неверный диск

Assign

AH=2 - мультиплексный номер для резидентной порции команды DOS 'ASSIGN'. Определена только подфункция AL=0 (дать статус установки).

Share

AH=10H - мультиплексный номер резидентной порции команды DOS 'SHARE'. Определена только подфункция AL=0 (дать статус установки).

Создание собственного процесса

Руководство DOS Tech Ref разъясняет, что вы можете использовать INT 2fH как вход для установки и доступа к вашему собственному резидентному процессу. Идея состоит в следующем: если вы произвольно используете вектор прерывания для вашего собственного доступа, то вы подвергаетесь определенному риску, особенно в мультизадачной системе. если же вы используете предлагаемую мультиплексную "цепочку", то DOS знает о вас, и ваш вектор не будет перекрыт другим обработчиком. Одна возможная проблема: нет предопределенного способа определить мультиплексный номер вашего процесса (регистр AH). Плохо привязываться к конкретному числу, ибо нет гарантии, что другой процесс не будет использовать этот же номер. Вы должны предусмотреть какую-то логику, гарантирующую вам четкое опознание вашего процесса.

Ваш процесс должен по меньшей мере использовать подфункцию AL=0, чтобы вы могли выяснить, не был ли процесс уже установлен ранее.

Замечание:

Если ваш процесс использует сервис DOS, или выполняется с незамаскированными прерываниями, то он должен быть реентерабельным.


Функции DOS - INT 22H: адрес завершения

INT 22H: адрес завершения

Адрес в этом векторе (0000:0088) представляет собой место, куда будет передано управление, когда текущая программа завершится по одной из следующих функций:

  • INT 20H (традиционный выход в DOS)
  • Функция DOS 00H
  • Функция DOS 4cH (EXIT)
  • INT 27H (TSR: завершиться, но остаться резидентным)
  • Функция DOS Fn 31H (KEEP)

DOS принимает во внимание этот вектор при снятии через INT 24H (критич.ошибка). Адрес в этом векторе копируется в поле PSP Terminate Address функциями DOS 26H (создать PSP) и 4bH (EXEC).

Не выдавайте INT 22h и не вызывайте этот адрес непосредственно.


Функции DOS - INT 23H: адрес выхода по Ctrl-Break

INT 23H: адрес выхода по Ctrl-Break

Адрес в этом векторе (0000:008c) - это адрес, по которому передается управление, когда DOS распознает, что пользователь нажал Ctrl-Break. Адрес по вектору INT 23H копируется в поле PSP Ctrl-Break Address функциями DOS 26H (создать PSP) и 4cH (EXEC). Исходное значение адреса обработчика Ctrl-Break восстанавливается из PSP при завершении программы. таким образом, по завершении порожденного процесса будет восстановлен адрес обработчика Ctrl-Break из родительского процесса.

Распознавание

DOS вызывает INT 23H, когда распознает, что нажата комбинация Ctrl-Break. Уровень чувствительности DOS к Ctrl-Break может быть проверен или установлен посредством функции 33H:

  • Если Break=ON, DOS распознает Ctrl-Break в течение всех функций, за исключением 06H и 07H.
  • Если Break=OFF, DOS распознает Ctrl-Break лишь во время операций ввода-вывода с консолью, принтером и последовательными портами.

Обработка

Обычная системная обработка Ctrl-Break вызывает немедленное снятие программы. чтобы перехватить обработку Ctrl-Break и передать ее вашей программе, воспользуйтесь следующими советами:

  • Вызовите функцию 25H , чтобы установить вектор INT 23H на ваш программный код.
  • При входе в ваш обработчик Ctrl-Break все регистры сохраняют те значения, которые они имели при входе в функцию DOS, распознавшую Ctrl-Break.
  • Если вы хотите игнорировать Ctrl-Break, просто выдайте IRET.
  • Если вы хотите что-нибудь сделать (скажем, прекратить повторение цикла), сохраните все регистры перед вашим действием и восстановите после действия. Выходите через IRET. Не существует ограничений для вашего обработчика - можно использовать все функции DOS. Однако, если обработчик Ctrl-Break сам выполняет символьный в/в, а пользователь вновь нажмет Ctrl-Break в это время, то DOS катастрофически сбивается.
  • Если вы хотите снять процесс (выйти в родительский процесс), установите флаг CF и выдайте FAR RET. это заставляет DOS выполнить обычную процедуру выхода в порождающий процесс.
  • Самый легкий способ убедиться, что процесс распознает нажатие Ctrl-Break - это время от времени вызывать функцию DOS 0bH.


Функции DOS - INT 24H: обработчик критических ошибок.

INT 24H: обработчик критических ошибок.

Этот вектор (0000:0090) хранит адрес, по которому передается управление, когда драйвер устройства DOS обнаруживает критическую ошибку. адрес по этому вектору копируется в PSP функицями 26H (создать PSP) и 4bH (EXEC). При выходе родительские значения восстанавливаются в векторе INT 24H из родительского PSP.

Нормальный обработчик INT 24H - это код, который выдает сообщение:

      Abort, Retry, Ignore? _

которое вы видите при неготовности дискеты или принтера.

Наиболее сложные программы предоставляют собственный обработчик критических ошибок.

Вход

При входе в обработчик INT 24H регистры содержат следующие данные:

  • BP:SI => заголовок устройства , позволяющий определить сбойное устройство
  • DI = биты 0-7 содержат код ошибки (биты 8-15 не определены)
  • AL = если в AH бит 7=0, то в AL номер диска (0=A, 1=B, и т.д.)
  • AH = информация об ошибке:

Вы можете обработать ошибку, запросив действие пользователя (например, подготовить дискету или включить принтер). функции DOS выше 0cH не следует использовать (исключая функцию 59H , которая работает нормально). Вы можете получить дополнительную информацию через функцию 59H и/или через блок заголовка устройства, адресуемый через BP:SI.

Выход

После обработки ошибки вы можете загрузить в регистр AL код действия и вернуться в DOS, указав одно из следующих действий:

  • AL=0: игнорировать ошибку
  • AL=1: повторить операцию
  • AL=2: снять. завершить через адрес INT 23H (как при Ctrl-Break)
  • AL=3: вернуться в приложение, индицируя сбившуюся функцию DOS

DOS 3.x проверьте AH при входе, чтобы определить допустимые действия. Опция AL=3 кажется идеальной. например, если операция "открыть файл" вызвала ошибку из-за отсутствия диска в устройстве, вы можете предоставить вашему приложению самому обработать эту ситуацию. Однако эта опция имеет недостатки:

  • Опция AL=3 НЕДОСТУПНА в версиях DOS младше 3.0
  • DOS всегда возвращает код ошибки 53H, который не очень информативен

Стек

При входе в обработчик INT 24H, стек имеет состояние, описанное ниже:

  • IP - адрес для возврата в DOS через IRET
  • CS - адрес для возврата в DOS через IRET
  • Flags
  • AX,BX,CX,DX,SI,DI,BP,DS,ES - регистры прикладной программы перед INT 21H
  • IP - адрес для возврата непосредственно в приложение
  • CS - адрес для возврата непосредственно в приложение
  • Flags - регистр флагов приложения

Эту информацию можно использовать, чтобы определить сбившуюся функцию (через AH в стеке) и любые параметры (через другие регистры). Но более существенно то, что ваш обработчик INT 24H может восстановить регистры и осуществить возврат непосредственно в прикладную программу.

Обычно ваш обработчик будет имитировать DOS, загружая AX кодом ошибки DOS и взводя флаг CF, чтобы индицировать ошибку (хорошие программы так и поступают). Когда вы возвращаетесь в приложение таким способом, то, как утверждается в документации, DOS будет в "неустойчивом" состоянии до тех пор, пока не будет вызвана функция с номером старше 0cH. Тем не менее, такая техника успешно используется многими программами.

Вектор INT 24H ИГНОРИРУЕТСЯ для дисковых ошибок, встречающихся при INT 25H/26H


Двоичная система счисления. Бит и байт. Сегментация памяти.

Автор: Олег Калашников
Источник: http://kalashnikoff.ru/Assembler/

Отрывок из книги «Ассемблер? Это просто! Учимся программировать»

Рассмотрим, как в памяти компьютера хранятся данные.

Вообще, как компьютер может хранить, например, слово "диск"? Главный принцип - намагничивание и размагничивание одной дорожки (назовем ее так). Одна микросхема памяти - это, грубо говоря, огромное количество дорожек. Сейчас попробуем разобраться. Например:

нуль будет обозначаться как 0000 (четыре нуля),

один 0001,
два  0010,

(т.е. правую единицу заменяем на 0 и вторую устанавливаем в 1).

Далее так:

три    0011
четыре 0100
пять   0101
шесть  0110
семь   0111
восемь 1000
девять 1001

и т.д.

Уловили принцип? "0" и "1" - это т.н. биты. Один бит, как вы уже заметили, может быть нулем или единицей, т.е. размагничена или намагничена та или иная дорожка ("0" и "1" это условное обозначение). Если еще присмотреться, то можно заметить, что каждый следующий установленный бит (начиная справа) увеличивает число в два раза: 0001 в нашем примере = 1; 0010 два; 0100 четыре; 1000 восемь и т.д. Это и есть т.н. двоичная форма представления данных.

Т.о. чтобы обозначить числа от 0 до 9 нам нужно четыре бита (хоть они и не до конца использованы. Можно было бы продолжить: десять 1010, одиннадцать 1011 , пятнадцать 1111).

Компьютер хранит данные в памяти именно так. Для обозначения какого-нибудь символа (цифры, буквы, запятой, точки...) в компьютере используется определенное количество бит. Компьютер "распознает" 256 (от 0 до 255) различных символов по их коду. Этого достаточно, чтобы вместить все цифры (0 - 9), буквы латинского алфавита (a - z, A - Z), русского (а - я, А - Я), а также другие символы. Для представления символа с максимально возможным кодом (255) нужно 8 бит. Эти 8 бит называются байтом. Т.о. один любой символ - это всегда 1 байт (см. рис. 1).

0 | 1 | 0 | 1 | 1 | 0 | 1 | 0
р | н | р | н | н | р | н | р

Рис. 1. Один байт с кодом буквы Z

(буквы н и р обозначают: намагничено или размагничено соответственно)

Можно элементарно проверить. Создайте в текстовом редакторе файл с любым именем и запишите в нем один символ, например, "М" (но не нажимайте Enter!). Если вы посмотрите его размер, то файл будет равен 1 байту. Если ваш редактор позволяет смотреть файлы в шестнадцатеричном формате, то вы сможете узнать и код сохраненного вами символа. В данном случае буква "М" имеет код 4Dh в шестнадцатеричной системе, которую мы уже знаем или 1001101 в двоичной.

Т.о. слово "диск" будет занимать 4 байта или 4*8 = 32 бита. Как вы уже поняли, компьютер хранит в памяти не сами буквы этого слова, а последовательность "единичек" и "ноликов". "Почему же тогда на экране мы видим текст, а не "единички-нолики"? - спросите вы. Чтобы удовлетворить ваше любопытство, я забегу немного вперед и скажу, что всю работу по выводу самого символа на экран (а не битов) выполняет видеокарта (видеоадаптер), которая находится в вашем компьютере. И если бы ее не было, то мы, естественно, ничего бы не видели, что у нас творится на экране.

В Ассемблере после двоичного числа всегда должна стоять буква "b". Это нужно для того, чтобы при ассемблировании нашей программы Ассемблер смог отличать десятичные, шестнадцатеричные и двоичные числа. Например: 10 - это "десять", 10h - это "шестнадцать" а 10b - это "два" в десятичной системе.

Т.о. в регистры можно загружать двоичные, десятичные и шестнадцатеричные числа.

Например:

mov ax,20
mov bh,10100b
mov cl,14h

В результате в регистрах AX, BH и CL будет находится одно и тоже число, только загружаем мы его в разных системах. Компьютер же будет хранить его в двоичном формате (как в регистре BH).

Итак, подведем итог. В компьютере вся информация хранится в двоичном формате (двоичной системе) примерно в таком виде: 10101110 10010010 01111010 11100101 (естественно, без пробелов. Для удобства я разделили биты по группам). Восемь бит - это один байт. Один символ занимает один байт, т.е. восемь бит. По-моему, ничего сложного. Очень важно уяснить данную тему, так как мы будем постоянно пользоваться двоичной системой, и вам необходимо знать ее на "отлично".

Как перевести двоичное число в десятичное:

Надо сложить двойки в степенях, соответствующих позициям, где в двоичном стоят единицы. Например:

Возьмем число 20. В двоичной системе оно имеет следующий вид: 10100b

Итак (начнем слева направо, считая от 4 до 0; число в нулевой степени всегда равно единице (вспоминаем школьную программу по математике)):

10100b = 1*24 + 0*23 + 1*22 + 0*21 + 0*20 = 20
---------------------------------------------
16+0+4+0+0 = 20

Как перевести десятичное число в двоичное:

Можно делить его на два, записывая остаток справа налево:

20/2 = 10, остаток 0
10/2=5, остаток 0
5/2=2, остаток 1
2/2=1, остаток 0
1/2=0, остаток 1

В результате получаем: 10100b = 20

Как перевести шестнадцатеричное число в десятичное:

В шестнадцатеричной системе номер позиции цифры в числе соответствует степени, в которую надо возвести число 16:

8Ah = 8*16 + 10 (0Ah) = 138

В настоящий момент есть множество калькуляторов, которые могут считать и переводить числа в разных системах счисления. Например, калькулятор Windows, который должен быть в инженерном виде. Очень удобен калькулятор и в DOS Navigator'е. Если у вас есть он, то отпадает необходимость в ручном переводе одной системы в другую, что, естественно, упростит вам работу. Однако, знать этот принцип крайне важно!

Сегментация памяти в DOS.

Возьмем следующее предложение: "Изучаем сегменты памяти". Теперь давайте посчитаем, на каком месте стоит буква "ы" в слове "сегменты" от начала предложения включая пробелы... На шестнадцатом. Подчеркну, что мы считали слово от начала предложения.

Теперь немного усложним задачу и разобьем предложение следующим образом (символом "_" обозначен пробел):

Пример N 1:

0000: Изучаем_
0010: сегменты_
0020: памяти
0030:

В слове "Изучаем" символ "И" стоит на нулевом месте; символ "з" на первом, "у" на втором и т.д. В данном случае мы считаем буквы начиная с нулевой позиции, используя два числа. Назовем их сегмент и смещение. Тогда, символ "ч" будет иметь следующий адрес: 0000:0003, т.е. сегмент 0000, смещение 0003. Проверьте...

В слове "сегменты" будем считать буквы начиная с десятой позиции, но с нулевого смещения. Тогда символ "н" будет иметь следующий адрес: 0010:0005, т.е. пятый символ начиная с десятой позиции. 0010 - сегмент, 0005 смещение. Тоже проверьте...

В слове "память" считаем буквы начиная с 0020 сегмента и также с нулевой позиции. Т.о. символ "а" будет иметь аодрес 0020:0001, т.е. сегмент 0020, смещение 0001. Опять проверим...

Итак, мы выяснили, что для того, чтобы найти адрес нужного символа необходимо два числа: сегмент и смещение внутри этого сегмента. В Ассемблере сегменты хранятся в сегментных регистрах: CS, DS, ES, SS (см. предыдущий выпуск), а смещения могут храниться в других (но не во всех).

Регистр CS служит для хранения сегмента кода программы (Code Segment - сегмент кода);

Регистр DS для хранения сегмента данных (Data Segment - сегмент данных);

Регистр SS для хранения сегмента стека (Stack Segment - сегмент стека);

Регистр ES дополнительный сегментный регистр, который может хранить любой другой сегмент (например, сегмент видеобуфера).

Пример N 2:

Давайте попробуем загрузить в пару регистров ES:DI сегмент и смещение буквы "м" в слове "памяти" из примера N 1 (см. выше). Вот как это запишется на Ассемблере:

(1) mov ax,0020
(2) mov es,ax
(3) mov di,2

Теперь в регистре ES находится сегмент с номером 20, а регистре DI смещение к букве "м" в слове "памяти". Проверьте, пожалуйста...

Здесь стоит отметить, что загрузка числа (т.е. какого-нибудь сегмента) напрямую в сегментый регистр запрещена. Поэтому мы в строке (1) загрузили сегмент в AX, а в строке (2) загрузили в регистр ES число 20, которое находилось в регистре AX:

mov ds,15 ---> ошибка!
mov ss,34h ---> ошибка!

Когда мы загружаем программу в память, она автоматически располагается в первом свободном сегменте. В файлах типа *.com все сегментные регистры автоматически инициализируются для этого сегмента (устанавливаются значения равные тому сегменту, в который загружена программа). Это можно проверить при помощи отладчика. Если, например, мы загружаем программу типа *.com в память, и компьютер находит первый свободный сегмент с номером 5674h, то сегментные регистры будут иметь следующие значения:

CS = 5674h
DS = 5674h
SS = 5674h
ES = 5674h

Код программы типа *.com должны начинаться со смещения 100h. Для этого мы, собственно, и ставили в наших прошлых примерах программ оператор org 100h, указывая Ассемблеру при ассемблировании использовать смещение 100h от начала сегмента, в который загружена наша программа (позже мы рассмотрим для чего это нужно). Сегментные же регистры, как я уже говорил, автоматически принимают значение того сегмента, в который загрузилась наша программа.

Пара регистров CS:IP задает текущий адрес кода. Теперь рассмотрим, как все это происходит на конкретном примере:

Пример N 3.

(1) CSEG segment
(2) org 100h
(3) _start:
(4) mov ah,9
(5) mov dx,offset My_name
(6) int 21h
(7) int 20h
(8) My_name db 'Oleg$'
(9) CSEG ends
(10) end _start

Итак, строки (1) и (8) описывают сегмент: CSEG (даем имя сегменту) segment (оператор Ассемблера, указывающий, что имя CSEG - это название сегмента); CSEG ends (end segment - конец сегмента) указывает Ассемблеру на конец сегмента.

Строка (2) сообщает, что код программы (как и смещения внутри сегмента CSEG) необходимо отсчитывать с 100h. По этому адресу в память всегда загружаются программы типа *.com.

Запускаем программу из Примера N 3 в отладчике. Допустим, она загрузилась в свободный сегмент 1234h. Первая команда в строке (4) будет располагаться по такому адресу:

1234h:0100h (т.е. CS = 1234h, а IP = 0100h) (посмотрите в отладчике на регистры CS и IP).

Перейдем к следующей команде (в отладчике CodeView нажмите клавишу F8, в другом посмотрите какая клавиша нужна; будет написано что-то вроде "F8-Step"). Теперь вы видите, что изменились следующие регистры:

AX = 0900h (точнее, AH = 09h, а AL = 0, т.к. мы загрузили командой mov ah,9 число 9 в регистр AH, при этом не трогая AL. Если бы AL был равен, скажем, 15h, то после выполнения данной команды AX бы равнялся 0915h)

IP = 102h (т.е. указывает на адрес следующей команды. Из этого можно сделать вывод, что команда mov ah,9 занимает 2 байта: 102h - 100h = 2).

Следующая команда (нажимаем клавишу F8) изменяет регистры DX и IP. Теперь DX указывает на смещение нашей строки ("Oleg$") относительно начала сегмента, т.е. 109h, а IP равняется 105h, т.е. адрес следующей команды. Нетрудно посчитать, что команда mov dx,offset My_name занимает 3 байта (105h - 102h = 3).

Обратите внимание, что в Ассемблере мы пишем:

mov dx,offset My_name

а в отладчике видим следующее:

mov dx,109 (109 - шестнадцатеричное число, но CodeView символ 'h' не ставит. Это надо иметь в виду).

Почему так происходит? Дело в том, что при ассемблировании программы, Ассемблер подставляет вместо offset My_name реальный адрес строки с именем My_name в памяти. Можно, конечно, записать сразу

mov dx,109h

Программа будет работать нормально. Но для этого нам нужно высчитать самим этот адрес. Попробуйте вставить следующие команды, начиная со строки (7) в примере N 3:

(7) int 20h
(8) int 20h
(9) My_name db 'Oleg$'
(10) CSEG ends
(11) end _start

Просто продублируем команду int 20h (хотя, как вы уже знаете, до строки (8) программа не дойдет).

Теперь ассемблируйте программу заново. Запускайте ее под отладчиком. Вы увидите, что в DX загружается не 109h, а другое число. Подумайте, почему так происходит. Это просто!

В окне "Memory" ("Память") вы должны увидеть примерно такое:

1234:0000 CD 20 00 A0 00 9A F0 FE = .a.
|N1_|_N2_| |_________N3__________| |N4_|

Позиция N1 (1234) - сегмент, в который загрузилась наша программа (может быть любым).

Позиция N2 (0000) - смещение в данном сегменте (сегмент и смещение отделяются двоеточием (:)).

Позиция N3 (CD 20 00 ... F0 FE) - код в шестнадцатеричной системе, который располагается с адреса 1234:0000.

Позиция N4 (= .a.) - код в ASCII (ниже рассмотрим), соответствующий шестнадцатеричным числам с правой стороны.

В Позиции N2 (смещение) введите значение, которое находится в регистре DX после выполнения строки (5). После этого в Позиции N4 вы увидите строку "Oleg$", а в Позиции N3 - код символов "Oleg$" в шестнадцатеричной системе... Вот что загружается в DX! Это не что иное, как АДРЕС (смещенеие) нашей строки в сегменте!

Но вернемся. Итак, мы загрузили в DX адрес строки в сегменте, который мы назвали CSEG (строки (1) и (9) в Прмере N 3). Теперь переходим к следующей команде: int 21h. Вызываем прерывание DOS с функцией 9 (mov ah,9) и адресом строки в DX (mov dx,offset My_name).

Как я уже говорил раньше, для использования прерываний в программах, в AH заносится номер функции. Номера функций нужно запоминать.

Наше первое прерывание.

Функция 09h прерывания 21h выводит строку на экран, адрес которой указан в регистре DX.

Вообще, любая строка, состоящая из ASCII символов, называется ASCII-строка. ASCII символы - это символы от 0 до 255 в DOS, куда входят буквы русского и латинского алфавитов, цифры, знаки препинания и пр.

Изобразим это в таблице (так всегда теперь будем делать):

Функция 09h прерывания 21h - вывод строки символов на экран в текущую позицию курсора:

Вход: AH = 09h, DX = адрес ASCII-строки символов, заканчивающийся '$'

Выход: ничего

В поле "Вход" мы указываем, в какие регистры что загружать, а в поле "Выход" - что возвращает функция. Сравните эту таблицу с Примером N 3.

Вот мы и рассмотрели сегментацию памяти. Если я что-то упустил, то это рассмотрим в последующих выпусках. Очень надеюсь на то, что вы разобрались в данной теме.

Теперь интересная программка для практики, которая выводит в верхний левый угол экрана веселую рожицу на синем фоне:

(1) CSEG segment
(2) org 100h
(3) _beg:
(4) mov ax,0B800h
(5) mov es,ax
(6) mov di,0
(7)
(8) mov ah,31
(9) mov al,1
(10) mov es:[di],ax
(11)
(12) mov ah,10h
(13) int 16h
(14)
(15) int 20h
(16)
(17) CSEG ends
(18) end _beg

Многие операторы вы уже знаете. Поэтому я буду объяснять только новые.

В данном примере мы используем вывод символа прямым отображением в видеобуфер.

В строках (4) и (5) загружаем в сегментный регистр ES число 0B800h, которое соответствует сегменту дисплея в текстовом режиме (запомните его!). В строке (6) загружаем в регистр DI нуль. Это будет смещение относительно сегмента 0B800h. В строках (8) и (9) в регистр AH заносится атрибут символа (31 - ярко-белый символ на синем фоне) и в AL - ASCII-код символа (01 - это рожица) соответственно.

В строке (10) заносим по адресу 0B800:0000h (т.е. первый символ в первой строке дисплея - верхний левый угол) атрибут и ASCII-код символа (31 и 01 соответственно) (сможете разобраться?).

Обратите внимание на запись регистров в строке (10). Скобки ( [ ] ) указывают на то, что надо загрузить число не в регистр, а по адресу, который содержится в регистре (в данном случае, как уже отмечалось, - это 0B800:0000h).

Можете поэксперементировать с данным примером. Только не меняйте строки (4) и (5). Сегментный регистр должен быть ES (можно, конечно, и DS, но тогда надо быть осторожным). Более подробно данный метод рассмотрим позже. Сейчас нам из него нужно понять принцип сегментации на практике.

Следует отметить, что вывод символа прямым отображением в видеобуфер является самым быстрым. Выполнение команды в строке (10) занимает 3 - 5 тактов. Т.о. на Pentium-100Mhz можно за секунду вывести 20 миллионов(!) символов или чуть меньше точек на экран! Если бы все программисты (а особенно Microsoft) выводили бы символы или точки на экран методом прямого отображения в видеобуфер на Ассемблере, то программы бы работали чрезвычайно быстро... Я думаю, вы представляете...

Комментарии пользователей (всего 4)

Restarter / 14 августа 2008, 23:13:08

Все вроде замеательно, но вот вывод методом прямого отображения в видеобуфер что-то не работает.
Это только у меня руки кривые, или здесь и в самом деле необходимы "пляски с бубном"?
система Win XP Pro SP2

ARVEN / 19 июля 2007, 08:37:39

Спасибо Вам большое! У нас в глухой деревне информатика не преподавалась, но я со школы мечтала стать программистом.Самообразованием занимаюсь, но этого недостаточно, знания слабые.В этом году я наконец-то поступаю на программиста, но абсолютный "чайник" в этом.Ваша статья многое прояснила. Очень понравилось :)

AvdotiaArturovna / 11 мая 2006, 23:48:29

Спасибо огромное. Я ненавижу математику и информатику, все это учу впервые, но мне все понятно!!!

MblLLl / 16 марта 2006, 12:39:27

Случайно забыли восьмеричную систему счисления !
Просто многим из уч. заведений она может пригодиться !
А так все супер ! Доходчиво и понятно ! какраз к перездаче готовлюсь ! :)


Недокументированные возможности MS-DOS - Комментарии к небольшой серии статей о недокументированных возможностях MS-DOS.

Комментарии к небольшой серии статей о недокументированных возможностях MS-DOS.

Описываемые возможности проникновения в DOS и недокументированное поведение функции 13h являются серьезной прорехой с точки зрения недопущения несанкционированных действий и в то же время лакомым кусочком для создателей вирусов. Существующие резидентные антивирусы не следят за этим способом проникновения в DOS, чем, кстати говоря, воспользовался вирус RD-1024. Ужасные же возможности функции 13h пока вроде бы еще не использовались и их еше не поздно закрыть. Для этого может быть использован драйвер, опубликованный в Dr.Dobb's Journal, текст которого здесь приводится. Почему-то о нем ничего не было сказано в "Софтпанораме", хотя, казалось бы, одна из функций бюллетеня - защита от вирусов. В результате пришлось отражать атаку нового вируса, воспользовавшегося именно этим способом.

Я вполне допускаю возможность вопроса о необходимости обнародования недокументированных возможностей MS-DOS, ибо это может вроде бы стимулировать создателей вирусов на новые творения. Однако нужно понимать, что авторы вирусов тоже любят читать всякие западные компьютерные журналы, где можно найти кое-что интересное по этой теме, как, например, вышеуказанная статья из Dr.Dobb's Journal. И своевременная информация принесла бы больше пользы, чем вреда, поскольку указанные прорехи были бы раньше закрыты, что свело бы на нет все усилия творцов вирусов. Вовремя эта информация не появилась, но лучше поздно, чем никогда, я надеюсь.

Необходимо заметить, что в процессе написания этой серии статей использовались материалы из статьи Closing the DOS Backdoor, опубликованной в Dr.Dobb's Journal. В то же время написанное не является переводом опубликованной статьи.

Если описанное заинтересовало кого-либо, если есть вопросы, замечания, пожелания - звоните или пишите.

[ Оглавление ]