Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метод_з_1.doc
Скачиваний:
15
Добавлен:
01.03.2025
Размер:
2.57 Mб
Скачать

Тема 5. Работа с прерываниями: перехват и восстановление.

Цель работы: Изучить алгоритм переопределения и восстановления прерываний. См. [2,9,14,21] и раздел 6.4 данного пособия.

Задание: 1.Написать программу в формате .COM и включить в неё подпрограмму обработки прерывания (процедуру обработки прерывания) на языке ассемблера; подпрограмма должна выдать сообщение на экран в соответствии с вариантом задания.

2. Ответить на контрольные вопросы.

Варианты задания (см. таблицу 9.1) отличаются номером используемого в программе прерывания и содержанием сообщения.

Замечания:

1. В основной программе перед загрузкой нового вектора прерывания необходимо сохранить старый вектор (функция 35h прерывания 21h)

2. Обработчик прерывания должен быть FAR-процедурой.

3. Для проверки работоспособности, новая процедура обработки прерывания должна выводить сообщение на экран.

4. В основной программе необходимо организовать большой по времени цикл, для того чтобы оставить на некоторое время загруженную программу в оперативной памяти (ОП). Это позволит увидеть на экране результат работы процедуры обработки прерывания. Самый простой способ не позволить операционной системе (ОС) выгрузить запущенную программу из ОП это ввести в основной программе перед передачей управления ОС строку с функцией ввода с клавиатуры одного символа. См. пример программы далее в этом разделе.

Прерывания и их переопределение.

Прерывание – это аппаратная функция, вызывающая приостановку операций процессора, запоминание его состояния и выполнение специальной программы, которая называется подпрограммой обработки прерывания или обработчиком прерывания (ISR).

Часто требуется выполнить одну из набора специальных процедур, если в системе или в программе возникают определенные условия, например, нажата клавиша на клавиатуре. Действие, стимулирующее выполнение одной из таких процедур, называется прерыванием. Существует два общих класса прерываний: внутренние и внешние. Первые инициируются состоянием ЦП или командой, а вторые - сигналом, подаваемым от других компонентов системы.

Переход к процедуре прерывания осуществляется из любой программы, а после выполнения процедуры прерывания обязательно происходит возврат в прерванную программу. Перед обращением к процедуре прерывания должно быть сохранено состояние всех регистров и флагов, используемых процедурой прерывания, а после окончания прерывания эти регистры должны быть восстановлены.

Последовательность прерывания состоит в следующем:

- текущее значение регистра Flags включается в стек:

- текущее значение регистра CS включается в стек:

- текущее значение регистра IP включается в стек:

- сбрасываются флаги IF и TF.

Новое содержимое IP и CS определяет начальный адрес выполняемой процедуры прерывания (обслуживание прерывания). Возврат в прерванную программу осуществляется командой, которая извлекает из стека содержимое для IP, CS и регистра флагов (обычно это команда IRET).

Адреса подпрограмм обслуживания прерываний (вектора прерываний) хранятся в таблице векторов прерываний. Таблица векторов прерываний располагается по адресу 0000:0000 и представляет собой массив из 256 элементов, каждый элемент которого занимает 4 байта и представляет собой начальный адрес процедуры обработки прерывания (см. раздел 6.4 «Организация прерываний»).

Иногда в программе возникает необходимость переопределения (перехвата) прерываний (например, выполнение дополнительных действий при нажатии определенной клавиши клавиатуры). «Перехватить» прерывание – значит, изменить его вектор так, чтобы он указывал на ваш собственный обработчик прерывания. Перед этим следует прочитать и сохранить старый вектор на тот случай, если потребуется обратиться по адресу исходного обработчика или восстановить прежнее значение вектора. Перед началом чтения или изменения вектора необходимо запретить аппаратные прерывания, чтобы исключить возможность модификации вектора в процессе чтения или возможность передачи управления по частично измененному вектору. Функции 25H и 35H обеспечивают это автоматически.

Процесс перехвата прерываний состоит в следующем:

- подготавливается FAR-процедура - новый обработчик прерываний (должна заканчиваться командой IRET);

- сохраняется старый вектор прерывания (функция 35h прерывания 21h)

- адрес нового обработчика заносится в таблицу векторов прерываний (функция 25h прерывания 21h);

- в конце программы происходит восстановление первоначального обработчика прерываний.

функция 35h

Вход: АН=35h

AL=номер прерывания (00h до 0ffh)

Выход: ES:BX= адрес обработчика прерывания

Описание: Возвращает значение вектора прерывания для INT (AL), то есть загружает в ВХ 0000:[AL*4], а в ES - 0000:[(AL*4)+2].

функция 25h.

Вход: АН=25Н

АL=номер прерывания (00h до 0ffh)

DS:DX=Beктop прерывания (адрес подпрограммы)

Выход: нет

Описание: Устанавливает значение элемента таблицы векторов прерываний для прерывания с номером AL равным DS:DX. Это равносильно записи 4-байтового адреса в 0000:(AL*4). Но, в отличие от прямой записи, в момент записи прерывания будут заблокированы.

Ниже приведён пример программы для перехвата прерывания с номером 1Ch; это прерывание вызывается автоматически по прерываниям от системного таймера каждые 55мс – (см. тему 6). Примечание: для вызова процедур обработчиков с другими номерами необходимо в тексте основной программы выполнить команду INTn, где n - № прерывания по варианту задания.

assume CS: code, DS:code

code segment

org 100h ; используем формат .COM

main proc ; начало основной программы

;установим адрес нашего обработчика на 1Сh прерывание. Это позволяет сделать функция 25h прерывания 21h. Но прежде нам нужно запомнить старый адрес этого прерывания. Для этого используется функция 35h прерывания 21h:

mov AX, 351Ch ;прочитаем исходный вектор прерывания 1Ch из табл. векторов

int 21h ; прерываний

mov word ptr old_, BX ; и сохраним его в нашей программе

mov word ptr old_ +2, ES ; в ячейке с именем old_

mov AX,2508h ;Установим наш обработчик

mov DX, offset new_1С ; в паре DS:DX адрес нового обработчика new_h

MOV DI, 0 ; начало выводимой строки на экране – верхний левый угол

; оставим программу в памяти компьютера до нажатия любой клавиши

mov АН, 01h ; функция ввода символа с клавиатуры

int 2Ih

;Завершим программу, восстановив сначала исходный вектор

lds DX, old_1C

mov AX, 2508h

int 21h

mov AX, 4C00h

int 21n

main endp ; окончание основной программы

;Наш обработчик прерываний от системного таймера будет выводить строку с сообщением каждые 55мс

; вывод сообщения осуществляется прямым отображением в видеобуфер

new_1C proc far

push AX ;Сохраним используемые

push ES ;регистры

push SI

push CX

mov AX,0B800h ; Настроим ES на начало

mov ES,AX ; видеобуфера - B800h

MOV SI, 0

MOV AH, 3Fh ; цвет и фон выводимых символов, 3Fh можно поменять на другое число

MOV CX, Len_str : число выводимых символов

; цикл вывода строки на экран прямым отображением в видеобуфер

M1: MOV AL, msg[SI]

MOV ES:[DI], AX

INC SI

INC DI ; для смещения на новую позицию экрана DI увеличиваем на 2

INC DI

Loop M1

Pop CX

POP SI

pop ES ;Восстановим

pop AX ;сохраненные регистры

iret ;Выход из обработчика

new_1С endp ; окончание процедуры new_1С

;Поля данных программы

old_ dd 0 ;Для хранения исходного вектора

msg db "Время истекло !' ;Информационное сообщение

Len_str = msg - $ ; длина строки

code ends

end main ; окончание основной программы

Установка обработчика в рассматриваемом примере выполняется проще, так как в основной программе используем формат .COM и нет необходимости настраивать регистр DS на сегмент данных - он и так уже настроен на единственный сегмент программы операционной системой. Установив обработчик, программа ожидает нажатия любой клавиши, для того чтобы успеть увидеть на экране выводимое сообщение. Текст обработчика прерывания new_1C настраивает сегментный регистр ES на область текстового видеобуфера и в цикле выводит строку с сообщением на экран, затем восстанавливает из стека используемые регистры.

В этом примере строка выводиться на экран пока не будет нажата любая клавиша.