Изучение принципов обработки аппаратных прерываний. Логика взаимодействия процессора и контроллера прерываний, страница 6

end_060:

pop                       es, di, ds, cx, bx, ax

iret

i08_hnd:

push                      ax, ds

mov                      ds, cs                     ;установка доступа к данным процедуры

inc                         cntr                       ;увеличение значения счетчика прерывании

cmp                       cntr, 18                 ;проверка на прохождение 1 минуты (~990 мсек)

jne                         l10

mov                       cntr, 0                   ;обнуление счетчика прерывании

int                         060                       ;вызов пользовательского прерывания

l10:

pop                       ds, ax

cs                   jmp                       old_v                    ;передача управления исходному обработчику

В данной программе использованы другие макросы для замены векторов прерывания. Внутри этих макросов замена производится не посредством функции dos 25h, а напрямую обращением к памяти. Кроме того, для предотвращения возникновения системных ошибок, на время замены вектора прерывания снят флаг разрешения аппаратных прерываний, т.е. аппаратные прерывания запрещены.

2.7.  Перехват прерывании от клавиатуры

Выход по «горячей клавише» - перехват аппаратного прерывания от клавиатуры int9h.

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

Out7.8

include                mac.inc

jmp                       start

old_v            dd                          ?             ;двойное слово для хранения значения вектора прерывания 08h

old_v1          dd                          ?             ;двойное слово для хранения значения вектора прерывания 060h

old_v2          dd                          ?             ;двойное слово для хранения значения вектора прерывания 09h

cntr                db                          0             ;счетчик прерываний от таймера

time                dw                         0

start:

schv                      old_v, 08, i08_hnd          ;замена ВП системного таймера с запретом внеш. прерыв.

schv                      old_v1, 060, i060_hnd    ;замена пользовательского ВП с запретом внеш. прерыв.

schv                      old_v2, 09, i09_hnd        ;замена ВП клавиатуры с запретом внеш. прерыв.

l1:

jmp                       l1;

i060_hnd:

push                      ax, bx, cx, ds, di, es

mov                      es, 0b800                            ;указатель на видеобуфер             

mov                      bx, 10

mov                      cx, 3

mov                      di, 6

mov                      ax, time

l2:

mov                      dx, 0                      ;преобразование числа секунд в ASCII код и отображение

div                        bx                          ;его на экране

add                        dl, '0'

dec                        di

es                   mov                      b [di], '.'

dec                        di

es                   mov                      [di], dl

loop                      l2

inc                         time

pop                        es, di, ds, cx, bx, ax

iret

i08_hnd:

push                      ax, ds

mov                      ds, cs                     ;установка доступа к данным процедуры

inc                         cntr                       ;увеличение значения счетчика прерывании

cmp                       cntr, 18                 ;проверка на прохождение 1 минуты (~990 мсек)

jne                         l10

mov                       cntr, 0                   ;обнуление счетчика прерывании