110 likes | 334 Views
ЛЕКЦИЯ № 2 Программирование контроллера прерываний
E N D
ЛЕКЦИЯ № 2 • Программирование контроллера прерываний • Программирование контроллера прерываний осуществляется через адресное пространство ввода-вывода посредством двух 8-битовых портов с адресами 20h и 21h. Управление контроллером осуществляется путем посылки в определенной последовательности в эти порты специальных приказов двух типов: • ICW (Initialization Control Word) –управляющее слово инициализации. Имеется 4 таких слова (ICW1 … ICW4)с жесткой внутренней структурой. • OCW (Operation Control Word) – операционное управляющее слово. Таких слова 3 (OCW1…OCW3) и с их помощью можно маскировать прерывания, управлять приоритетом, считывать состояние регистров контроллера и т.п.
Приказы BIOS для инициализации контроллера прерываний
ОБРАБОТКА ПРЕРЫВАНИЙ В РЕАЛЬНОМ РЕЖИМЕ • Основной особенностью является фиксированное расположение в памяти таблицы векторов прерываний (ТВП) в диапазоне адресов 00000h-003ffh (первый килобайт оперативной памяти). Она содержит 256 векторов прерываний - адресов процедур обработки прерываний в формате сегмент:смещение (следует иметь в виду, что в памяти смещение предшествует сегментной части, и младшие байты расположены по младшим адресам). • ЭТАПЫ ОБРАБОТКИ ПРЕРЫВАНИЙ • Прекращение выполнения текущей программы. • Переход к выполнению и выполнение программы обработки прерываний. • Возврат управления прерванной программе. • На первом этапе процессором автоматически сохраняется в стеке содержимое трех регистров: cs, eip/ip, eflags/flags. В конце первого этапа процессор автоматически сбрасывает флаг IF (но при этом в стек записывается предыдущее содержимое регистра флагов).
Дамп памяти с фрагментом таблицы векторов прерываний 0000:0000 E8 4E 9A 01 00 00 00 00-C3 E2 00 F0 00 00 00 00 0000:0010 F0 01 70 00 54 FF 00 F0-05 18 00 F0 05 18 00 F0 0000:0020 2C 08 51 17 D0 0A 51 17-AD 08 54 08 E8 05 01 2F 0000:0030 FA 05 01 2F 05 18 00 F0-57 EF 00 F0 F0 01 70 00 0000:0040 90 13 C7 13 4D F8 00 F0-41 F8 00 F0 3E 0A 51 17 0000:0050 5C 00 B7 25 59 F8 00 F0-E2 0A 51 17 9C 00 B7 25 0000:0060 00 00 00 F6 8E 00 DE 09-6E FE 00 F0 F2 00 7B 09 0000:0070 27 08 51 17 A4 F0 00 F0-22 05 00 00 00 00 00 F0 Вектор прерывания таймера, номер которого 8h, имеет значение 1751:082С.
Второй этап начинается с определения источника прерывания и вызова соответствующей программы обработки. Для вызова программы обработки используется ТВП. Определить адрес, по которому находится нужный вектор прерывания можно следующим образом: • смещение_элемента_таблицы векторов_прерываний = n*4 • На втором этапе микропроцессор выполняет следующие действия: • По номеру источника прерывания путем умножения на 4 определяет смещение в ТВП; • Помещает первые 2 байта по вычисленному адресу в ip; • Помещает вторые 2 байта по вычисленному адресу в cs; • Передает управление по адресу cs:ip. • Содержание 3 этапа содержит действия, выполняемые автоматически, и меры, предпринимаемые программистом, разрабатывающим программу обработки прерывания.
По команде iret автоматически из стека восстанавливаются регистры eflags/flags, ip, cs. Однако этого обычно недостаточно. Если в программе обработки прерывания использовались какие-либо регистры, то в начале необходимо сохранить эти регистры в стеке, а перед возвратом, восстановить значения этих регистров и очистить стек. При этом на время сохранения и восстановления регистров следует отключать прерывания, используя команды cli, sti. Написание собственного прерывания Использования собственных процедур обработки прерываний требует корректировки ТВП. Наиболее удобно для этого использовать функции операционной системы. В частности, функция 25h прерывания 21h устанавливает вектор прерываний на указанный адрес.
;- - - установка прерывания 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. отметим, что функция 25H автоматически запрещает аппаратные прерывания в процессе изменения вектора, поэтому не существует опасности, что посреди дороги произойдет аппаратное прерывание, использующее данный вектор. Основные отличительные особенности написания процедуры обработки прерывания видны из следующего фрагмента
;- - - процедура прерывания ROUT PROC FAR PUSH AX ;сохраняем все изменяемые регистры … POP AX ;восстанавливаем регистры MOV AL,20H ;эти две строки надо использовать OUT 20H,AL ;только для аппаратных прерываний IRET ROUT ENDP Когда программа завершается, должны быть восстановлены оригинальные вектора прерываний. B противном случае последующая программа может вызвать данное прерывание и передать управление на то место в памяти, в котором Вашей процедуры уже нет. Функция 35 прерывания 21H возвращает текущее значение вектора прерывания, помещая значение сегмента в ES, a смещение в BX. перед установкой своего прерывания следует получить текущее значение вектора, используя эту функцию, сохранить эти значения, и затем восстановить их c помощью функции 25H (как выше) перед завершением своей программы.
Пример: ;- - - в сегменте данных: KEEP_CS DW 0 ;хранит сегмент заменяемого прерывания KEEP_IP DW 0 ;хранит смещение прерывания ;- - - в начале программы MOV AH,25H ;функция получения вектора MOV AL,1CH ;номер вектора INT 21H ;теперь сегмент в ES, смещение в BX MOV KEEP_IP,BX ;запоминаем смещение 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
Сохранять, изменять и восстанавливать вектора прерываний можно и без использования функций операционной системы в ситуации, когда размещение ТВП в памяти известно. Необходимо только в момент изменения вектора отключать прерывания. • При разработке собственных процедур обработки прерываний можно использовать следующие механизмы: • Дополнять существующие прерывания; • Заменять существующие прерывания собственными; • Дополнять существующие прерывания собственными процедурами. • Для дополнения существующих прерываний можно использовать несколько способов. • 1. Некоторые стандартные процедуры обработки прерываний программно (командой int) генерируют вызов фиктивных прерываний, процедуры обработки которых состоят из одной команды iret. Заменив такую процедуру собственной можно дополнять существующее прерывание новыми возможностями. Так процедура обработки прерывания таймера
с номером вектора 8h делает вызов такого фиктивного прерывания с номером вектора 1Ch. 2. Можно изменить номер вектора существующего прерывания, скопировав его на свободное место в ТВП. А на его прежнее место записать вектор, адресующий собственную процедуру, которая в свою очередь вызывает стандартную процедуру по новому номеру прерывания. Это позволяет либо до вызова стандартной процедуры, либо после него, запрограммировать собственные действия. Например, можно, пользуясь тем, что при обработке прерываний от клавиатуры всегда вызывается функция 09h прерывания BIOS 16h . По изложенной выше методике можно предварить получение символа из буфера клавиатуры или дополнить собственными действиями.