 
        
        - •Лекции 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
