- •Лекции 19-20
- •Понятие прерывания
- •Аппаратное прерывание
- •Аппаратное прерывание
- •Аппаратные прерывания
- •Номера IRQ аппаратных
- •Исключения
- •Программное прерывание
- •Программное окружение прерываний
- •Таблица прерываний
- •Прерывание 10h (Видео
- •Прерывание 16h (клавиатура)
- •Прерывание 21h (сервис DOS)
- •Функции консольного вывода
- •Функции консольного ввода
- •Функции файлового ввода -
- •Функции файлового ввода - вывода
- •Функции работы с памятью
- •Пример
- •Пример
- •Пример
- •;------ Cycle for read & write -----------
- •next4:
- •Перехват прерываний
- •Перехват прерываний
- •Перехват прерываний
- •Перехват прерываний
- •Перехват прерываний
- •Создание собственных обработчиков прерываний
- •Создание собственных обработчиков прерываний
- •Создание собственных обработчиков прерываний
- •Пример 1
- •Обработчик (начало инсталятора)
- •Обработчик (вывод сообщения о наличии
- •Обработчик (инсталляция)
- •Пример использования
- •Пример 2
- •Обработчик (код обработки - продолжение)
- •Обработчик (начало инсталятора)
- •Обработчик (вывод сообщения о наличии
- •Обработчик (инсталляция)
- •Пример 3
- •Обработчик (начало инсталятора)
- •Обработчик (вывод сообщения о наличии
- •Обработчик (инсталляция)
Создание собственных обработчиков прерываний
Можно создавать собственные обработчики программных прерываний. Для этого осуществляется «перехват» не используемого программного прерывания (как правило это прерывания с номерами 31h и более).
Программа которая осуществила «перехват» прерывания и установила свой собственный обработчик этого прерывания завершается, но остается резидентной (остается в памяти ЭВМ).
Остальные программы, которые запускаются после установки обработчика, могут использовать сервис предоставляемый этим прерыванием.
Создание собственных обработчиков прерываний
Программа осуществляющая создание обработчика программного прерывания как правило выполняет два действия: инсталлирование обработчика, деинсталлирование обработчика.
Инсталлирование обработчика осуществляется только, если он не был установлен ранее.
Деинсталлирование обработчика осуществляется только если он был установлен ранее.
Создание собственных обработчиков прерываний
НАЧАЛО
Нет |
Обработчик уже установлен |
Да |
|
|
|
|
|
|
|
|
|
|
|
|
Нет |
|
Необходимо удалить |
Да |
|||||
Установить обработчик |
|
|
|
|
обработчик |
|
|
||||
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Выйти, оставшись |
|
Вывести сообщение |
|
Удалить обработчик |
|||||||
резидентным |
|
о его наличии |
|
||||||||
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
КОНЕЦ
Пример 1
Написать программу, которая бы устанавливала обработчик прерывания 51h. Обработчик используя сервис MS DOS должен вывести сообщение на экран “It is handler!”. Программа по умолчанию (если обработчика нет) должна устанавливать обработчик прерывания 51h. Если обработчик уже есть, то:
если в параметрах командной строки первым символом передан символ ‘u’ убрать обработчик прерывания,
если в параметрах командной строки нет первого символа ‘u’, то вывести сообщении об уже установленном обработчике.
Дополнительно реализовать программу, которая бы использовала прерывание 51h.
|
|
Обработчик (код |
|
|||||
|
||||||||
|
|
обработки) |
|
|
|
|
||
.486 |
|
|
|
|
|
|
||
model tiny |
|
|
|
|
|
|
||
Code SEGMENT use16 |
|
|
|
|
||||
|
|
|
ASSUME |
cs:Code, ds:Code, ss:Code |
|
|
|
|
start: |
org |
100h |
|
|
|
|
||
jmp |
start0 |
|
|
|
|
|||
|
|
|
|
|
|
|
||
oldvec |
dd |
0 |
;Ячейка для хранения старого вектора прерывания |
|||||
flag |
dw |
0FDFDh |
;Ячейка флага установленного прерывания |
|||||
handler: |
mov |
ah,09h |
;Функция 21h прерывания для вывода строки на экран |
|||||
|
|
|
||||||
|
|
|
push |
ds |
;Сохранение регистра DS |
|||
|
|
|
push |
dx |
;Сохранение регистра DX |
|||
|
|
|
push |
cs |
;Установка DS на CS |
|||
|
|
|
pop |
ds |
; |
|
|
|
|
|
|
mov |
dx, offset mess0 |
;Помещение в DX смещения сообщения mess0 |
|||
|
|
|
int |
21h |
;Вызов прерывания 21h |
|||
|
|
|
pop |
dx |
;Восстановление DX |
|||
|
|
|
pop |
ds |
;Восстановление DS |
|||
|
|
|
iret |
|
;Завершение прерывания |
|||
mess0 |
db |
'It is handler!',0dh,0ah,'$‘ |
; |
|
|
|||
|
|
|
|
|
|
|
|
|
Обработчик (начало инсталятора)
start0: |
|
|
|
|
xor |
ax, ax |
;Устанавливаем ES:[DI] на вектор |
|
mov |
es, ax |
;обработчика прерывания 51h |
|
mov |
di, (51h * 4) |
|
|
mov |
ax, es:[di] |
;Устанавливаем DS:[SI] на адрес |
|
mov |
si, ax |
;обработчика прерывания |
|
mov |
ax, es:[di+2] |
|
|
mov |
ds, ax |
|
|
mov |
ax, ds:[si-2] |
;Заносим в AX значение перед обработчиком |
|
cmp |
ax, 0FDFDh |
;Проверка наличия флага |
|
jz |
next0 |
|
|
jmp |
install |
;Переход на установку вектора |
next0: |
|
|
|
|
mov |
al, cs:[82h] |
;Проверка символа ‘u’ в параметрах |
|
cmp |
al, 'u‘ |
;командной строки |
|
jz |
remove |
;Переход на удаление обработчика |
|
|
|
|
Обработчик (вывод сообщения о наличии
|
обработчика или удаление) |
|||
|
push |
cs |
;Установка DS на CS |
|
|
pop |
ds |
|
|
|
mov |
dx, offset mess1 |
;Заносим в DX смещение mess1 |
|
|
mov |
ah, 09h |
;В AH функцию вывода строки |
|
|
int |
21h |
;Вызов прерывания 21h |
|
|
int |
20h |
;Завершение программы |
|
remove: |
|
|
|
|
|
mov |
ax, ds:[si-6] |
;Восстановление старого вектора прерывания |
|
|
mov |
es:[di], ax |
|
|
|
mov |
ax, ds:[si-4] |
|
|
|
mov |
es:[di+2], ax |
|
|
|
|
push |
ds |
;Освобождение памяти |
|
|
pop |
es |
|
|
|
mov |
ah, 49h |
|
|
|
int |
21h |
|
|
push |
cs |
;Установка DS на CS |
|
|
pop |
ds |
|
|
|
mov |
ah, 09h |
;В AH функцию вывода строки |
|
|
mov |
dx, offset mess3 |
;Заносим в DX смещение mess3 |
|
|
int |
21h |
;Вызов прерывания 21h |
|
|
int |
20h |
;Завершение программы |
|
|
|
|
|
|
Обработчик (инсталляция)
install: |
|
|
|
push |
cs |
;Устанавливаем DS на CS |
|
pop |
ds |
|
|
mov |
si, offset oldvec |
;В SI заносим смещение oldvec |
|
mov |
ax, es:[di] |
;Сохраняем в oldvec адрес старого обработчика |
|
mov |
ds:[si], ax |
|
|
mov |
ax, es:[di+2] |
|
|
mov |
ds:[si+2], ax |
|
|
mov |
ax, cs |
;Устанавливаем в таблице векторов прерывания |
|
mov |
es:[di+2], ax |
;Адрес нового обработчика прерывания 51h |
|
mov |
ax, offset handler |
|
|
mov |
es:[di], ax |
|
|
mov |
ah, 09h |
;Выводим сообщение об успешной установке |
|
mov |
dx, offset mess2 |
;обработчика прерывания 51h |
|
int |
21h |
|
|
mov |
dx, offset start0 |
;Завершаем программу, оставляя ее резидентной |
|
int |
27h |
|
|
mess1 |
db |
'Handler already installed!',0dh,0ah,'$' |
|
mess2 |
db |
'Handler installed!',0dh,0ah,'$' |
|
mess3 |
db |
'Handler removed!',0dh,0ah,'$' |
Code ENDS end start
Пример использования
.486 model tiny
Code SEGMENT use16
ASSUME cs:Code, ds:Code, ss:Code org 100h
start:
int 51h int 20h Code ENDS
end start
Пример 2
Необходимо выполнить перехват прерывания клавиатуры (09h) и заблокировать возможность «теплой перезагрузки» (т.е. Ctrl+Ald+Del).
|
|
Обработчик (код |
|
|||
|
|
|||||
|
|
обработки) |
|
|
||
.486 |
|
|
|
|
||
model tiny |
|
|
|
|
||
Code SEGMENT use16 |
|
|
||||
|
|
|
ASSUME |
cs:Code, ds:Code, ss:Code |
|
|
start: |
org |
100h |
|
|
||
jmp |
start0 |
|
|
|||
|
|
|
|
|
||
oldvec |
dd |
0 |
;Ячейка для хранения старого вектора прерывания |
|
||
flag |
dw |
0FDFDh |
;Ячейка флага установленного прерывания |
|
||
handler: |
push |
ax |
;Сохраняем AX |
|
||
|
|
|
|
|||
|
|
|
in |
al, 60h |
;Читаем SCAN-код нажатой клавиши |
|
|
|
|
cmp |
al, 83 |
;Сравниваем со значением DEL |
|
|
|
|
jz |
testAC |
;Если равно, то на testAC |
|
testAC: |
jmp |
oldhnd |
;Переход на стандартную обработку |
|
||
push |
es |
;Сохранение es |
|
|||
|
|
|
|
|||
|
|
|
xor |
ax, ax |
;Очистка ax |
|
|
|
|
mov |
es, ax |
;Установка es на начало памяти |
|
|
|
|
mov |
al, es:[0417h] |
;Запись в al значения состояния спец. клавиш |
|
|
|
|
pop |
es |
;Восстановление es |
|
|
|
|
and |
al, 12 |
;Обнуление всех бит, кроме 2 и 3 |
|
|
|
|
|
|
|
|