Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2 курс / Лекции / Лекция 19 - 20 - Прерывания.ppt
Скачиваний:
46
Добавлен:
18.02.2023
Размер:
609.28 Кб
Скачать

Обработчик (код обработки - продолжение)

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