- •Лекции 19-20
- •Понятие прерывания
- •Аппаратное прерывание
- •Аппаратное прерывание
- •Аппаратные прерывания
- •Номера IRQ аппаратных
- •Исключения
- •Программное прерывание
- •Программное окружение прерываний
- •Таблица прерываний
- •Прерывание 10h (Видео
- •Прерывание 16h (клавиатура)
- •Прерывание 21h (сервис DOS)
- •Функции консольного вывода
- •Функции консольного ввода
- •Функции файлового ввода -
- •Функции файлового ввода - вывода
- •Функции работы с памятью
- •Пример
- •Пример
- •Пример
- •;------ Cycle for read & write -----------
- •next4:
- •Перехват прерываний
- •Перехват прерываний
- •Перехват прерываний
- •Перехват прерываний
- •Перехват прерываний
- •Создание собственных обработчиков прерываний
- •Создание собственных обработчиков прерываний
- •Создание собственных обработчиков прерываний
- •Пример 1
- •Обработчик (начало инсталятора)
- •Обработчик (вывод сообщения о наличии
- •Обработчик (инсталляция)
- •Пример использования
- •Пример 2
- •Обработчик (код обработки - продолжение)
- •Обработчик (начало инсталятора)
- •Обработчик (вывод сообщения о наличии
- •Обработчик (инсталляция)
- •Пример 3
- •Обработчик (начало инсталятора)
- •Обработчик (вывод сообщения о наличии
- •Обработчик (инсталляция)
Обработчик (код обработки - продолжение)
cmp |
al, 12 |
;Сравнение с 12 |
|
jnz |
oldhnd |
;Если не равно, то переход на стандартную обработку |
|
mov |
al, 20h |
;Подтверждение обработки аппаратного прерывания |
|
out |
20h, al |
;контроллеру прерываний |
|
pop |
ax |
;Восстановление AX |
|
iret |
|
;Завершение прерывания |
|
oldhnd: |
|
|
|
pop |
ax |
;Восстановление AX |
|
jmp |
dword ptr cs:oldvec |
;Переход по старому вектору |
Обработчик (начало инсталятора)
start0: |
|
|
|
|
xor |
ax, ax |
;Устанавливаем ES:[DI] на вектор |
|
mov |
es, ax |
;обработчика прерывания 09h |
|
mov |
di, (09h * 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: |
|
|
|
|
|
cli |
;Запрет прерываний |
|
|
|
mov |
ax, ds:[si-6] |
|
;Восстановление старого вектора прерывания |
|
mov |
es:[di], ax |
|
|
|
mov |
ax, ds:[si-4] |
|
|
|
mov |
es:[di+2], ax |
|
|
|
sti |
;Разрешение прерываний |
||
|
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 |
|
cli |
;Запрет прерываний |
|
|
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 |
;Адрес нового обработчика прерывания 09h |
|
mov |
ax, offset handler |
|
|
mov |
es:[di], ax |
|
|
sti |
;Разрешение прерываний |
||
mov |
ah, 09h |
;Выводим сообщение об успешной установке |
|
mov |
dx, offset mess2 |
;обработчика прерывания 09h |
|
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
Пример 3
Реализовать резидентную программу, которая бы перехватывала прерывание таймера (08h) и каждую секунду включала один из индикаторов ScrollLock, CapsLock, NumLock на клавиатуре в указанной последовательности (циклически).
Для включения индикаторов используется команда 0edh контролера клавиатуры. После этой команды необходимо отправить байт, содержащий информацию о состоянии индикаторов: bit0 – ScrollLock, bit1 – NumLock, bit2 – CapsLock.
|
|
Обработчик (код |
|
|||
|
|
|||||
|
|
обработки) |
|
|
||
.486 |
|
|
|
|
||
model tiny |
|
|
|
|
||
Code SEGMENT use16 |
|
|
||||
|
|
|
ASSUME |
cs:Code, ds:Code, ss:Code |
|
|
start: |
org |
100h |
|
|
||
jmp |
start0 |
|
|
|||
|
|
|
|
|
||
counter |
db |
0 |
;Ячейка для счета «тиков» таймера |
|
||
value |
db |
4 |
;Ячейка для хранения следующего индикатора |
|
||
oldvec |
dd |
0 |
;Ячейка для хранения старого вектора прерывания |
|
||
flag |
dw |
0FDFDh |
;Ячейка флага установленного прерывания |
|
||
handler: |
pusha |
|
;Сохранение всех РОН |
|
||
|
|
|
|
|
||
|
|
|
push |
ds |
;Сохранение DS |
|
|
|
|
push |
cs |
;Установка DS на CS |
|
|
|
|
pop |
ds |
; |
|
|
|
|
mov |
al, byte ptr counter |
;Чтение в AL счетчика «тиков» |
|
|
|
|
inc |
al |
;Инкремент счетчика |
|
|
|
|
mov |
byte ptr counter, al |
;Сохранение нового значения |
|
|
|
|
cmp |
al, 18 |
;Проверка: прошла ли секунда |
|
|
|
|
jnz |
toexit |
;Если еще нет, то переход на старый обработчик |
|
|
|
|
xor |
al, al |
;Очистка счетчика |
|
|
|
|
mov |
byte ptr counter, al |
;Сохранение нового значения |
|
|
|
|
|
|
|
|
|
Обработчик (код обработки - |
|
|||||
|
продолжение) |
|
|
||||
|
|
|
xor |
cx, cx |
;Очистка CX |
|
|
wait01: |
;Ожидание готовности контроллера клавиатуры |
|
|||||
|
|
|
in |
al, 64h |
|
|
|
|
|
|
and |
al, 00000010b |
|
|
|
|
|
|
loopnz |
wait01 |
|
|
|
|
|
|
mov |
al, 0edh |
;Запись команды в AL |
|
|
|
|
|
out |
60h, al |
;Отправка команды контроллеру |
|
|
|
|
|
xor |
cx, cx |
|
|
|
wait02: |
;Ожидание готовности контроллера клавиатуры |
|
|||||
|
|
|
in |
al, 64h |
|
|
|
|
|
|
and |
al, 00000010b |
|
|
|
|
|
|
loopnz |
wait02 |
|
|
|
|
|
|
mov |
al, byte ptr value |
;Запись в AL нового состояния индикаторов |
|
|
|
|
|
out |
60h, al |
;Отправка нового состояния контроллеру |
|
|
|
|
|
shr |
al, 1 |
;Определение следующего состояния |
|
|
|
|
|
mov |
byte ptr value, al |
;Сохранение следующего состояния |
|
|
|
|
|
or |
al, al |
;Проверка на 0 |
|
|
|
|
|
jnz |
toexit |
; |
|
|
|
|
|
mov |
al, 4 |
;Переход состояния по циклу |
|
|
toexit: |
mov |
byte ptr value, al |
;Сохранение следующего состояния |
|
|||
pop |
ds |
;Восстановление DS |
|
||||
|
|
|
|
||||
|
|
|
popa |
;Восстановление всех РОН |
|
||
|
|
|
jmp |
dword ptr cs:oldvec |
;Переход по старому вектору |
|
|
|
|
|
|
|
|
|
|
Обработчик (начало инсталятора)
start0: |
|
|
|
|
xor |
ax, ax |
;Устанавливаем ES:[DI] на вектор |
|
mov |
es, ax |
;обработчика прерывания 08h |
|
mov |
di, (08h * 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: |
|
|
|
|
|
cli |
;Запрет прерываний |
|
|
|
mov |
ax, ds:[si-6] |
|
;Восстановление старого вектора прерывания |
|
mov |
es:[di], ax |
|
|
|
mov |
ax, ds:[si-4] |
|
|
|
mov |
es:[di+2], ax |
|
|
|
sti |
;Разрешение прерываний |
||
|
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 |
|
cli |
;Запрет прерываний |
|
|
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 |
;Адрес нового обработчика прерывания 08h |
|
mov |
ax, offset handler |
|
|
mov |
es:[di], ax |
|
|
sti |
;Разрешение прерываний |
||
mov |
ah, 09h |
;Выводим сообщение об успешной установке |
|
mov |
dx, offset mess2 |
;обработчика прерывания 08h |
|
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