Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Написание собственного прерывания



Существует несколько причин для написания собственного пре­рывания. Во-первых, большинство из готовых прерываний, обеспечи­ваемых операционной системой, не что иное, как обычные процедуры, доступные для всех программ, и вы можете пожелать добавить свое в эту библиотеку. Например, многие ваши программы могут использо­вать процедуру, выводящую строки на экран вертикально. Вместо то­го, чтобы включать ее в каждую программу в качестве процедуры, вы можете установить ее как прерывание, написав программу, которая останется резидентной в памяти после завершения. Тогда вы можете использовать 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              ; хранит сегмент заменяемого

;прерывания
KEEP_JP DW О                          ; хранит смещение прерывания

;---- в начале программы

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; Просмотров: 171; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.023 с.)
Главная | Случайная страница | Обратная связь