Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Написание собственного прерывания
Существует несколько причин для написания собственного прерывания. Во-первых, большинство из готовых прерываний, обеспечиваемых операционной системой, не что иное, как обычные процедуры, доступные для всех программ, и вы можете пожелать добавить свое в эту библиотеку. Например, многие ваши программы могут использовать процедуру, выводящую строки на экран вертикально. Вместо того, чтобы включать ее в каждую программу в качестве процедуры, вы можете установить ее как прерывание, написав программу, которая останется резидентной в памяти после завершения. Тогда вы можете использовать INT 80H вместо WRITE_VERT (вызов прерывания несколько медленнее, чем процедуры). Во-вторых, причиной написания прерывания может быть использование какого-либо отдельного аппаратного прерывания. Это прерывание автоматически вызывается при возникновении определенных условий. В некоторых случаях BIOS инициализирует вектор этого прерывания так, что он указывает на процедуру, которая вообще ничего не делает (она содержит один оператор IRET). Вы можете написать свою процедуру и изменить вектор прерываний, чтобы он указывал на нее. Тогда при возникновении аппаратного прерывания будет выполняться ваша процедура. Одна из таких процедур - это прерывание времени суток, которое автоматически вызывается 18,2 раза в секунду. Обычно это прерывание только обновляет показание часов, но вы можете добавить к нему любой код. Если ваш код проверяет показания часов и вступает в игру в определенные моменты времени, то возможны операции в реальном времени. Другие возможности - написание процедур обработки "Ctrl-Break", "PrtScr" и возникновения ошибочных ситуаций. Прерывания принтера и коммуникационные позволяют компьютеру быстро переключаться между операциями ввода/вывода и другой обработкой. Наконец, вам просто захотелось написать прерывание, которое полностью заменит одну из процедур операционной системы, приспособленное к вашим нуждам. Функция 25Н прерывания 21Н устанавливает вектор прерывания на указанный адрес. Адреса имеют размер в два слова. Старшее слово содержит значение сегмента (CS), младшее содержит смещение (IP). Чтобы установить вектор, указывающий на одну из ваших процедур, нужно поместить сегмент процедуры в DS, а смещение в DX. Затем поместить номер прерывания в AL и вызвать функцию. Любая процедура прерывания должна заканчиваться не обычной инструкцией RET, a IRET (выталкивает из стека три слова, включая регистр флагов, в то время как RET помещает в стек только два). Функция 25Н автоматически запрещает аппаратные прерывания в процессе изменения вектора, поэтому не существует опасности, что посреди дороги произойдет аппаратное прерывание, использующее данный вектор. ;----- установка прерывание PUSH DS ;сохраняем DS MOV DX,OFFSET ROUT ;смещение для процедуры в DX MOV AX,SEG ROUT ;сегмент процедуры MOV DS,AX ;помещаем в DS MOV AH,25H ;функция установки вектора MOV AL,60H ;номер вектора INT 21H ;меняем прерывание POP DS восстанавливаем DS ;----- процедура прерывания ROUTINE PROC FAR PUSH AX ;сохраняем все изменяемые регистры • • • POP AX восстанавливаем регистры MOV AL,20H ;эти две строки используются OUT 20H,AL ;только для аппаратных прерываний IRET ROUTINE ENDP В конце кода каждого из аппаратных прерываний необходимо включать следующие строчки: MOV AL,20H OUT 20H,AL Если аппаратное прерывание не оканчивается этими строками, то микросхема 8259 не очистит информацию регистра обслуживания, с тем чтобы была разрешена обработка прерываний с более низкими уровнями, чем только что обработанное. Отсутствие этих строк легко может привести к сбою программы, так как прерывания от клавиатуры, скорее всего, будут замороженными и даже Ctrl-Alt-Del окажется бесполезным. Отметим, что эта добавка не нужна для векторов прерываний, являющихся расширениями существующих прерываний, таких, как прерывание 1СН, которое добавляет код к прерыванию времени суток. Когда программа завершается, должны быть восстановлены оригинальные векторы прерываний. В противном случае последующая программа может вызвать данное прерывание и передать управление на то место в памяти, в котором вашей процедуры уже нет. Функция 35 прерывания 21Н возвращает текущее значение вектора прерывания, перемещая значение сегмента в ES, а смещение в ВХ. Перед установкой своего прерывания получите текущее значение вектора, используя эту функцию, сохраните эти значения и затем восстановите их с помощью функции 25Н (как выше) перед завершением своей программы. Например: ;---- в сегменте данных KEEP__CS DW 0 ; хранит сегмент заменяемого ;прерывания ;---- в начале программы MOV АН,25Н функция получения вектора MOV AL,1CH номер вектора INT 21H теперь сегмент в ES, смещение в ВХ MOV КЕЕР__1Р,ВХ запоминаем смещение MOV KEEP__CS,ES запоминаем сегмент ;---- в конце программы CLI PUSH DS ;DS будет разрушен MOV DX,KEEP_IP ;подготовка к восстановлению MOV AX,KEEP_CS ; MOV DS,AX ;подготовка к восстановлению MOV AH,25H ;функция установки вектора MOV AL,1CH ;номер вектора INT 21H ;восстанавливаем вектор POP DS восстанавливаем DS STI Существуют "ловушки", которых необходимо избегать при написании прерывания. Если новая процедура прерывания должна иметь доступ к данным, то необходимо позаботиться, чтобы DS был правильно установлен. Другая неприятность может состоять в том, что при завершении программы по "Ctrl-Break" вектор прерывания не будет восстановлен (т.е. необходимо предусмотреть, чтобы при нажатии "Ctrl-Break" программа выполняла эту процедуру). Рассмотренные выше функции MS DOS просто получают или изменяют пару слов в младших ячейках памяти. Смешение вектора может быть вычислено простым умножением номера вектора на 4. Например, чтобы получить адрес прерывания 16Н в ES:BX, нужно: ;----- получение адреса прерывания 16Н SUB AX,AX устанавливаем ES на начало памяти MOV ES,AX MOV DI,16H ;номер прерывания в DI SHL 01,1 ;умножаем на 2 SHL DI,1 ; MOV BX,ES:[DI] ;берем младший байт в ВХ MOV AX,ES:[DI]+2 ;берем старший байт в ES MOV ES,AX Не рекомендуется прямо устанавливать вектор прерываний, обходя функцию DOS. В частности в многозадачной среде операционная система может поддерживать несколько таблиц векторов прерываний, и реальный физический адрес таблицы может быть известен только DOS.
|
Последнее изменение этой страницы: 2019-04-21; Просмотров: 186; Нарушение авторского права страницы