Bazaprogram.ru

Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Прерывание int 21h ассемблер

Ассемблер

Прерывание 21h: общие функции DOS

Все функции DOS вызываются с помощью прерывания 21h (в десятичной нотации 33). Первая версия DOS содержала 42 функции. Во второй к ним добавлено еще 33 функции, которые сохраняются во всех последующих версиях. Выбор конкретной функции осуществляется путем записи соответствующего номера в регистр AH.

Функция 02: вывод одного символа на экран

Для вывода одного символа на экран ПК используется

функция 02 прерывания 21h:

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

Особым образом осуществляется вывод символов с кодами 7, 8, 9, 10 (0Ah) и 13 (0Dh). Символ с кодом 7 (bell, звонок) на экране не высвечивается (и курсор не сдвигается), а вызывает звуковой сигнал. Символ с кодом 8 (backspase, шаг назад) возвращает курсор на одну позицию влево, если только он не был в самой левой позиции строки. Символ с кодом 9 (tab, табуляция) смещает курсор вправо на ближайшую позицию, кратную 8. Символ с кодом 10 (line feed, перевод строки) перемещает курсор в следующую строку экрана, оставляя его в той же колонке. Символ с кодом 13 (carrige returne, возврат каретки) устанавливает курсор на начало текущей строки; вывод подряд символов с кодами 13 и 10 означает перевод курсора на начало следующей строки.

Функция 9: вывести строку на экран дисплея

Для вывода на экран строки (последовательности символов) можно, конечно, использовать функцию 02, однако сделать это можно и за один прием с помощью функции 09 прерывания 21h:

DS:DX := начальный адрес строки

Перед обращением к этой функции в регистр DS должен быть помещен номер того сегмента памяти, в котором находится выводимая строка, а в регистр DX — смещение строки внутри этого сегмента. При этом в конце строки должен находиться символ $ (код 24h), который служит признаком конца строки и сам не выводится.

Хотя эта функция может оказаться намного удобнее функций побайтового вывода на экран (функция 2 и 6), она имеет тот недостаток, что вполне обычный символ $ используется как ограничитель строки. Это еще один побочный продукт совместимости с CP/M.

Расширенные функции операционной системы DOS в качестве ограничителя строки используют CHR$(0). Это соответствует соглашениям, принятым в операционной системе UNIX и языке программирования Си.

Среди функций DOS нет такой, которая выводит числа. Такую операцию, если надо, приходится реализовывать на основе рассмотренных функций.

Функция 4Ch: завершение программы

Завершив все свои действия, программа обязана вернуть управление операционной системе, чтобы пользователь мог продолжить работу на ПК. Такой возврат реализуется функцией 4Ch прерывания 21h, которую помещают в конце программы:

Каждая программа, вообще говоря, обязана сообщить, успешно или нет она завершила свою работу. Дело в том, что любая программа вызывается из какой-то другой программы (например, из операционной системы), и иногда вызвавшей программе, чтобы правильно продолжить работу, надо знать, выполнила ли вызванная программа все, что надо, или она проработала с ошибкой. Такая информация передается в виде кода завершения программы (некоторого целого числа), который должен быть нулевым, если программа проработала правильно, и ненулевым (каким именно — оговаривается в каждом случае особо) в противном случае. (Узнать код завершения вызванной программы можно с помощью функции 4Dh прерывания 21h.) Потребуется этот код или нет, программа все равно должна выдать его.

Читать еще:  0xc00000ba ошибка как устранить

Перехват int 21h

Assembler
11.12.2019, 19:18

Перехват int 21h
Подскажите пожалуйста. Как передать управление оригинальному обработчику 21h? CSEG Segment.

Перехват int 21h
com 16 bit .286 ASKII_code_key_check equ ‘A’ ASKII_code_key equ ‘B’.

Перехват прерывания int 21h
Немного решил поэкспериментировать. Есть два случая для сравнения. Первый случай (работает).

Резидентная программа — перехват int 21h ah=09h
Помогите пожалуйста Надо написать резидентную программу, которая будет активироватьcя при попытки.

12.12.2019, 16:012
Assembler
12.12.2019, 16:51 [ТС]3
12.12.2019, 18:594
Assembler
12.12.2019, 19:195
Assembler
12.12.2019, 19:236
12.12.2019, 20:477

Как-то делал перехват int 1Ch из exe программы. Смысл тот же.
Сейчас попробую разобраться.

Добавлено через 1 час 22 минуты
proc3nt, у меня не получилось устанавливать новый вектор при помощи самого int 21h. А вот всё то же самое, но при прямой записи в память таблицы векторов — отлично работает.

Assembler
13.12.2019, 12:238

proc3nt Вы пишите

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

Есть другой простой способ вызывать старое прерывание:

Assembler
Assembler
13.12.2019, 14:349

Думаю, что мы имеем дело с программным прерыванием и регистр ds никто не меняет — иначе бы не распечатывалась строка ds:dx при вызове функции ah=09h.

Мне не удавалось выполнить замену вектора int 21h средствами самого int 21h. Видимо, это связано как-то с внутренним устройством «родного» обработчика. Думаю, чтобы исключить такое влияние, корректнее напрямую заменять вектор.

Добавлено через 7 минут
Очень может быть, что «родной» обработчик int 21h в некоторых случаях рекурсивно обращается к int 21h уже после замены ds.
Поэтому адрес перехода лучше хранить в сегменте кода и выполнять косвенных переход по адресу в переменной из сегмента данных. А вот регистр ds перед переходом — не устанавливать на cs.

Поэтому примеры com программ выглядят проще, и не дают представления о происходящем — когда с виду корректная программа, зависает.

Добавлено через 38 минут
Т.е. так вижу:
— адрес оригинального обработчика хранится в сегменте кода
— в собственном обработчике перед передачей управления оригинальному обработчику сегмент данных не изменяется (поэтому адрес и храним сегменте кода).

Так работает.
А предыдущий код из сообщения #7, скорее всего некорректный

Прерывание int 21h ассемблер

В прошлом шаге мы использовали команду INT:

Int — это сокращение слова Interrupt что на русский переводиться как прерывание. Выглядит это команда так:

То есть у каждого прерывания есть номер. И все таки, что это такое? Появилось понятие прерывания вместе с созданием ЭВМ. Тогда стала задача о совместной работе процессора и медленных внешних устройств. Хорошим примеров может служить клавиатура. Когда пользователь нажмет клавишу не известно. Это может случиться в любой момент, вот когда он нажимает клавишу и сообщается процессору что нужно бы обработать это дело и получить клавишу, которая нажата. Отсюда можно сделать вывод, что прерывания рождают внешние устройства. Но мы же с Вами использовали прерывание в программе. Конечно, кроме получения информации от устройства, этим устройствами нужно еще и управлять. Устройства медленные и помимо прочего еще нужно будет дождаться окончание выполнения операции. Это то же реализуется с помощью прерываний только вызываем их мы из программы. Итак, прерывания бывают двух типов:

  • Программные
  • Аппаратные

Я еще как бы хочу акцентировать внимание на проблемах, которые были связанны с появлением прерываний. Устройств всяких много — клавиатура, монитор, дисковод и так далее. Если не пользоваться прерываниями, то постоянно операционная система должна опрашивать устройства, нажата ли клавиша, хотите ли вывести данные на монитор и так далее. Намного проще оговорить некоторый механизм который и будет обращаться внимание операционной системы и процессора на необходимость проведения некоторых действий. Итак, давайте посмотрим на все это в динамике. Ваша программа что то считает. В этот момент нажимается клавиша. Программа должны быть прервана. И это будет сделано, управление будет передано специальному коду (процедура обработки прерывания) а потом Ваша программа будет выполняться дальше. То же самое когда мы вызываем прерывание для вывода символов на монитор (int 21h 04Ch) то сами генерируем прерывание. Зачем ? В этот момент может происходить считывание с дисковода или вывод других символов на экран. А тут мы не с того не с сего со своими символами. Так как прерывания могут наступать одновременно, то есть приоритет их обработки. Есть прерывание, которые выполняться в любом случае даже если идет обработка другого прерывания. Процедура обработки прерывания это программа. Вопрос в том только где она храниться. Базовая обработка прерывания храниться в BIOS и в самих микросхемах оборудования. Но использовать их довольно тяжело. Представьте, для того , что бы записать файл нужно завести двигатель дисковода, установить головку, дать команду перейти в тот сектор прочитать таблицу файлов, проверить что там нет файла и так далее так далее. Все эти задачи облегчает операционная система, которая предоставляет Вам прерывания более высоко уровня. Используя эти прерывания, Вы можете одним заходом создать файл, например. Различают прерывания по номерам:

Вот когда Вы вызываете прерывание (INT) Вы указываете еще и номер (21h) то есть, кто будет выполнять это действие.

Прерывание int 21h ассемблер

На этом шаге мы рассмотрим основные операции над файлами .

Перечислим основные операции, организующие работу с файлами в расширенной версии DOS .

1. Создание файла (функция 3CH) . Регистр DX должен содержать адрес ASCIIZ -строки, а регистр CX — необходимый атрибут (для обычного файла значение атрибута равно 0):

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

В случае возникновения ошибки операция устанавливает флаг CF в 1 и помещает в регистр AX код возврата: 03, 04 или 05 . Код 05 свидетельствует либо о переполнении оглавления, либо о защите существующего файла атрибутом «только для чтения».

2. Запись файла (функция 40H) . В регистре BX должен быть установлен файловый номер, в регистре CX — число записываемых байт, а в регистре DX — адрес области вывода.

В следующем примере происходит запись 256 байт из области OUTREC :

Правильно выполненная операция записывает из памяти на диск все данные (256 байт), очищает флаг CF и устанавливает в регистре AX число действительно записанных байтов. Если диск переполнен, то число записанных байтов может отличаться от заданного числа. В случае неправильной операции флаг CF устанавливается в 1, а в регистр AX заносится код 05 (нет доступа) или 06 (ошибка файлового номера).

3. Закрытие файла (функция 3EH) . В регистре BX должен находиться файловый номер. Эта операция записывает все оставшиеся еще данные из буфера на диск, корректирует оглавление и таблицу FAT :

В случае ошибки в регистре AX устанавливается код 06 (неправильный файловый номер).

4. Чтение дискового файла (функция 3DH) . Эта операция проверяет правильность имени файла и его наличие на диске. При открытии файла регистр DX должен содержать адрес необходимой ASCIIZ -строки, а регистр AL — код доступа:

  • 00H — открыть файл только для ввода (чтение из файла);
  • 01H — открыть файл только для вывода (запись в файл);
  • 02H — открыть файл для ввода и вывода.

Ниже приведен пример открытия файла для чтения:

Если файл с необходимым именем существует, то операция открытия устанавливает длину записи, равной 1, принимает существующий атрибут, сбрасывает флаг CF и заносит файловый номер в регистр AX .

Если файл отсутствует, то операция устанавливает флаг CF и заносит в регистр AX код ошибки: 02, 04, 05 или 12 .

5. Чтение записей файла (функция 3FH) . В регистре BX нужно установить файловый номер, в регистре CX — число читаемых байтов и в регистре DX — адрес области ввода. В следующем примере происходит считывание записи длиной 512 байт:

Правильно выполненная операция считывает запись в память, сбрасывает флаг CF и устанавливает в регистре AX число действительно прочитанных байтов. Нулевое значение в регистре AX обозначает попытку чтения после конца файла. Ошибочная операция устанавливает флаг CF и возвращает в регистре AX код ошибки: 05 (нет доступа) или 06 (ошибка файлового номера).

На следующем шаге мы перечислим дополнительные операции над файлами .

Ссылка на основную публикацию
Adblock
detector