Как формируются прерывания по событию в 1986. Прерывания и особые ситуации: Типы прерываний

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

Кажется очевидным, что возможны самые разнообразные прерывания по самым различным причинам. Поэтому прерывание рассматривается не просто как таковое: с ним связывают число, называемое номером типа прерывания или просто номером прерывания. С каждым номером прерывания связывается то или иное событие. Система умеет распознавать, какое прерывание, с каким номером оно произошло, и запускает соответствующую этому номеру процедуру.

Программы могут сами вызывать прерывания с заданным номером. Для этого они используют команду INT. Это так называемые программные прерывания. Программные прерывания не являются асинхронными, так как вызываются из программы (а она-то знает, когда она вызывает прерывание!).

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

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

Использование прерываний при работе с медленными внешними устройствами позволяют совместить ввод/вывод с обработкой данных в центральном процессоре и в результате повышает общую производительность системы.

Некоторые прерывания (первые пять в порядке номеров) зарезервированы для использования самим центральным процессором на случай каких-либо особых событий вроде попытки деления на ноль, переполнения и т.п.

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

Заметим еще, что обработчики прерываний могут сами вызывать программные прерывания, например, для получения доступа к сервису BIOS или DOS (сервис BIOS также доступен через механизм программных прерываний).

Составление собственных программ обработки прерываний и замена стандартных обработчиков DOS и BIOS является ответственной и сложной работой. Необходимо учитывать все тонкости работы аппаратуры и взаимодействия программного и аппаратного обеспечения. При отладке возможно разрушение операционной системы с непредсказуемыми последствиями, поэтому надо очень внимательно следить за тем, что делает Ваша программа.

4.2. Таблица векторов прерываний

Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти - адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов - FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний. В первом слове элемента таблицы записано смещение, а во втором - адрес сегмента обработчика прерывания.

Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с номером 1 - 0000:0004 и т.д. Для программиста, использующего язык Си, таблицу можно описать следующим образом:

void (* interrupt_table)();

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

Займемся теперь содержимым таблицы векторов прерываний. Приведем назначение некоторых наиболее важных векторов:

Номер Описание
0 Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). DOS обычно при обработке этого прерывания выводит сообщение об ошибке и останавливает выполнение программы. Для процессора 8086 при этом адрес возврата указывает на следующую после команды деления команду, а в процессоре 80286 - на первый байт команды, вызвавшей прерывание.
1 Прерывание пошагового режима. Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после выполнения команды MOV в сегментные регистры или после загрузки сегментных регистров командой POP.
2 Аппаратное немаскируемое прерывание. Это прерывание может использоваться по-разному в разных машинах. Обычно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора.
3 Прерывание для трассировки. Это прерывание генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания.
4 Переполнение. Генерируется машинной командой INTO, если установлен флаг OF. Если флаг не установлен, то команда INTO выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций.
5 Печать копии экрана. Генерируется при нажатии на клавиатуре клавиши PrtScr. Обычно используется для печати образа экрана. Для процессора 80286 генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона.
6 Неопределенный код операции или длина команды больше 10 байт (для процессора 80286).
7 Особый случай отсутствия математического сопроцессора (процессор 80286).
8
9 IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных от клавиатуры.
A
B
C
D
E
F
10 Обслуживание видеоадаптера.
11 Определение конфигурации устройств в системе.
12 Определение размера оперативной памяти в системе.
13 Обслуживание дисковой системы.
14 Последовательный ввод/вывод.
15 Расширенный сервис для AT-компьютеров.
16 Обслуживание клавиатуры.
17 Обслуживание принтера.
18 Запуск BASIC в ПЗУ, если он есть.
19
1A Обслуживание часов.
1B Обработчик прерывания Ctrl-Break.
1C Прерывание возникает 18.2 раза в секунду, вызывается программно обработчиком прерывания таймера.
1D Адрес видеотаблицы для контроллера видеоадаптера 6845.
1E Указатель на таблицу параметров дискеты.
1F Указатель на графическую таблицу для символов с кодами ASCII 128-255.
20-5F Используется DOS или зарезервировано для DOS.
60-67 Прерывания, зарезервированные для пользователя.
68-6F Не используются.
70
71
72 IRQ10 - зарезервировано.
73 IRQ11 - зарезервировано.
74 IRQ12 - зарезервировано.
75
76
77 IRQ15 - зарезервировано.
78 - 7F Не используются.
80-85 Зарезервированы для BASIC.
86-F0 Используются интерпретатором BASIC.
F1-FF Не используются.

IRQ0 - IRQ15 - это аппаратные прерывания, о них будет рассказано позже.

4.3. Маскирование прерываний

Часто при выполнении критических участков программ, для того чтобы гарантировать выполнение определенной последовательности команд целиком, приходится запрещать прерывания. Это можно сделать командой CLI. Ее нужно поместить в начало критической последовательности команд, а в конце расположить команду STI, разрешающую процессору воспринимать прерывания. Команда CLI запрещает только маскируемые прерывания, немаскируемые всегда обрабатываются процессором.

Если вы используете запрет прерываний с помощью команды CLI, следите за тем, чтобы прерывания не отключались на длительный период времени, так как это может привести к нежелательным последствиям. Например, будут отставать часы.

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

4.4. Изменение таблицы векторов прерываний

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

Очень важно не забыть перед завершением работы восстановить содержимое измененных векторов в таблице прерываний, т.к. после завершения работы программы память, которая была ей распределена, считается свободной и может быть использована для загрузки другой программы. Если вы забыли восстановить вектор и пришло прерывание, то система может разрушиться - вектор теперь указывает на область, которая может содержать что угодно.

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

  • прочитать содержимое элемента таблицы векторов прерываний для вектора с нужным вам номером;
  • запомнить это содержимое (адрес старого обработчика прерывания) в области данных программы;
  • установить новый адрес в таблице векторов прерываний так, чтобы он соответствовал началу Вашей программы обработки прерывания;
  • перед завершением работы программы прочитать из области данных адрес старого обработчика прерывания и записать его в таблицу векторов прерываний.

Кроме того, операция изменения вектора прерывания должна быть непрерывной в том смысле, что во время изменения не должно произойти прерывание с номером, для которого производится замена программы обработки. Если вы, например, запишете новое значение смещения, а сегментный адрес обновить не успеете, то по какому адресу будет передано управление в случае прерывания и что при этом произойдет? Об этом можно только догадываться.

Для облегчения работы по замене прерывания DOS предоставляет в Ваше распоряжение специальные функции для чтения элемента таблицы векторов прерывания и для записи в нее нового адреса. Если вы будете использовать эти функции, DOS гарантирует, что операция по замене вектора будет выполнена правильно. Вам не надо заботиться о непрерывности процесса замены вектора прерывания.

Для чтения вектора используйте функцию 35h прерывания 21h. Перед ее вызовом регистр AL должен содержать номер вектора в таблице. После выполнения функции в регистрах ES:BX будет искомый адрес обработчика прерывания.

Функция 25h прерывания 21h устанавливает для вектора с номером, находящимся в AL, обработчик прерывания DS:DX.

Разумеется, вы можете непосредственно обращаться к таблице векторов прерываний, но тогда при записи необходимо замаскировать прерывания командой CLI, не забыв разрешить их после записи командой STI.

Для пользователей языка Си библиотека Quick C содержит функции _dos_getvec(), _dos_setvect(). Первая функция получает адрес из таблицы векторов прерываний, вторая устанавливает новый адрес.

Если вам надо добавить какие-либо собственные действия к тем, что выполняет стандартный обработчик прерывания, то можно организовать цепочку прерываний.

Для организации цепочки прерываний вы записываете в векторную таблицу адрес своего обработчика, не забыв сохранить прежнее содержимое таблицы. Ваш обработчик получает управление по прерыванию, выполняет какие-либо действия, затем передает управление стандартному обработчику. Можно сделать и по-другому: ваш обработчик вызывает стандартный обработчик как подпрограмму, после возврата из стандартного обработчика выполняет дополнительные действия. То есть вы можете вставить дополнительную обработку как до вызова стандартного обработчика, так и после его вызова.

В библиотеке Quick C имеется функция для организации цепочки прерываний - _chain_intr().

Рассмотрим более подробно возможности библиотеки интегрированной среды Quick C, предназначенные для работы с прерываниями.

Модификатор interrupt (_interrupt для Quick C 2.5 и C 6.0) описывает функцию, которая является обработчиком прерывания. Такая функция завершается командой возврата из обработки прерывания IRET, и для нее автоматически генерируются команды сохранения регистров на входе и их восстановления при выходе из обработчика прерывания. Пример использования модификатора для описания функции обработки прерывания:

void interrupt far int_funct(void) { // Тело обработчика прерывания }

Функция обработки прерывания должна быть FAR-функцией, т.к. таблица векторов прерываний содержит полные адреса в виде сегмент:смещение.

Ключевое слово interrupt используется также для описания переменных, предназначенных для хранения векторов прерываний:

void (_interrupt _far *oldvect)(void);

Модификаторы _interrupt и _far для Quick C 2.5 и C 6.0 являются синонимами соответственно interrupt и far.

Какие требования предъявляются к программе обработки прерывания?

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

Для установки своего обработчика прерываний используйте функцию _dos_setvec. Эта функция имеет два параметра - номер прерывания и указатель на новую функцию обработки прерывания. Например:

_dos_setvect(0x16, my_key_intr);

В этом примере для клавиатурного прерывания с номером 16h устанавливается новый обработчик прерывания my_key_intr.

Если вам надо узнать адрес старого обработчика прерывания по его номеру, лучше всего воспользоваться функцией _dos_getvect, которая принимает в качесте параметра номер прерывания и возвращает указатель на соответствующий этому номеру в таблице векторов прерываний обработчик. Например:

old_vector = _dos_getvect(0x16);

Для организации цепочки прерываний используйте функцию _chain_intr. В качестве параметра эта функция принимает адрес старого обработчика прерываний.

Следующий простой пример иллюстрирует применение всех трех функций, предназначенных для работы с прерываниями. Эта программа встраивает собственный обработчик прерывания таймера, который будет вызываться примерно 18,2 раза в секунду. Встраиваемый обработчик прерывания считает тики таймера и, если значение счетчика кратно 20, на динамик компьютера выдается звуковой сигнал. В конце работы новая программа обработки прерывания таймера вызывает старый обработчик с помощью функции _chain_intr.

После установки нового обработчика прерывания таймера основная программа ждет нажатия на клавиатуре любой клавиши, затем она восстанавливает старое содержимое вектора прерывания.

#include #include #include // Выключаем проверку стека и указателей #pragma check_stack(off) #pragma check_pointer(off) // Это макро используется для выдачи // сигнала на внутренний динамик // компьютера. Используется вывод // в формате TTY символа BELL (7) // через прерывание BIOS 10h #define BEEP() _asm { _asm mov bx,0 _asm mov ax, 0E07h _asm int 10h } void main(void); // Объявление программы обработки прерывания void _interrupt _far timer(void); // Эта переменная предназначена для хранения // старого значения вектора прерывания // таймера. Она должна быть глобальной. void (_interrupt _far *oldvect)(void); // Переменная для подсчета тиков таймера volatile long ticks; void main(void) { ticks=0L; // Сбрасываем счетчик тиков таймера oldvect = _dos_getvect(0x1c); // Запоминаем адрес // старого обработчика // прерывания _dos_setvect(0x1c, timer); // Устанавливаем свой // обработчик printf("nТаймер установлен. Нажмите любую" "клавишу...n"); getch(); // Ожидаем нажатия на любую клавишу _dos_setvect(0x1c,oldvect); // Восстанавливаем старый // обработчик прерывания // таймера exit(0); } // Функция обрабатывает прерывания таймера void _interrupt _far timer(void) { ticks++; // Увеличиваем счетчик тиков таймера // Если значение счетчика тиков кратно 20, // выдаем сигнал на динамик компьютера if((ticks % 20) == 0) BEEP(); // Вызываем старый обработчик прерывания _chain_intr(oldvect); }

4.5. Особенности обработки аппаратных прерываний

Аппаратные прерывания вырабатываются устройствами компьютера, когда возникает необходимость их обслуживания. Например, по прерыванию таймера соответствующий обработчик прерывания увеличивает содержимое ячеек памяти, используемых для хранения времени. В отличие от программных прерываний, вызываемых запланировано самой прикладной программой, аппаратные прерывания всегда происходят асинхронно по отношению к выполняющимся программам. Кроме того, может возникнуть одновременно сразу несколько прерываний!

Для того, чтобы система "не растерялась", решая какое прерывание обслуживать в первую очередь, существует специальная схема приоритетов. Каждому прерыванию назначается свой уникальный приоритет. Если происходит одновременно несколько прерываний, то система отдает предпочтение самому высокоприоритетному, откладывая на время обработку остальных прерываний.

Система приоритетов реализована на двух микросхемах Intel 8259 (для машин класса XT - на одной такой микросхеме). Каждая микросхема обслуживает до восьми приоритетов. Микросхемы можно объединять (каскадировать) для увеличения количества уровней приоритетов в системе.

Уровни приоритетов обозначаются сокращенно IRQ0 - IRQ15 (для машин класса XT существуют только уровни IRQ0 - IRQ7).

Для машин XT приоритеты линейно зависели от номера уровня прерывания. IRQ0 соответствовало самому высокому приоритету, за ним шли IRQ1, IRQ2, IRQ3 и так далее. Уровень IRQ2 в машинах класса XT был зарезервирован для дальнейшего расширения системы и, начиная с машин класса AT, IRQ2 стал использоваться для каскадирования контроллеров прерывания 8259. Добавленные приоритетные уровни IRQ8 - IRQ15 в этих машинах располагаются по приоритету между IRQ1 и IRQ3.

Приведем таблицу аппаратных прерываний, расположенных в порядке приоритета:

Номер Описание
8 IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду.
9 IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных с клавиатуры.
A IRQ2 - используется для каскадирования аппаратных прерываний в машинах класса AT.
70 IRQ8 - прерывание от часов реального времени.
71 IRQ9 - прерывание от контроллера EGA.
72 IRQ10 - зарезервировано.
73 IRQ11 - зарезервировано.
74 IRQ12 - зарезервировано.
75 IRQ13 - прерывание от математического сопроцессора.
76 IRQ14 - прерывание от контроллера жесткого диска.
77 IRQ15 - зарезервировано.
B IRQ3 - прерывание асинхронного порта COM2.
C IRQ4 - прерывание асинхронного порта COM1.
D IRQ5 - прерывание от контроллера жесткого диска для XT.
E IRQ6 - прерывание генерируется контроллером флоппи-диска после завершения операции.
F IRQ7 - прерывание принтера. Генерируется принтером, когда он готов к выполнению очередной операции. Многие адаптеры принтера не используют это прерывание.

Из таблицы видно, что самый высокий приоритет у прерываний от интервального таймера, затем идет прерывание от клавиатуры.

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

Наиболее интересными с точки зрения программирования контроллера прерываний являются регистры маски прерываний IMR и управляющий регистр прерываний.

В машинах класса XT регистр маски прерываний имеет адрес 21h, управляющий регистр прерываний - 20h. Для машин AT первый контроллер 8259 имеет такие же адреса, что и в машинах XT, регистр маски прерываний второго контроллера имеет адрес A1h, управляющий регистр прерываний - A0h.

Разряды регистра маски прерываний соответствуют номерам IRQ. Для того чтобы замаскировать аппаратное прерывание какого-либо уровня, надо заслать в регистр маски байт, в котором бит, соответствующий этому уровню, установлен в 1. Например, для маскирования прерываний от НГМД в порт 21h надо заслать двоичное число 01000000.

Приведем пример программы, маскирующей прерывание от флоппи-диска:

#include #include #include void main(void); void main(void) { outp(0x21,0x40); printf("nПрерывания от флоппи-диска запрещены.n"); exit(0); }

Эта программа есть на дискете, прилагающейся к книге. Запустите ее (с жесткого диска) и попробуйте поработать, например, с дисководом А:. У вас ничего не получится!

Чтобы "оживить" флоппи-диски, запустите программу, которая размаскирует все прерывания (в том числе и от флоппи):

#include #include #include void main(void); void main(void) { outp(0x21,0); printf("nПрерывания от флоппи-диска разрешены.n"); exit(0); }

Заметьте, что мы только что замаскировали прерывание именно от флоппи-диска, все остальные устройства продолжали нормально работать. Если бы мы выдали машинную команду CLI, то отключились бы все аппаратные прерывания. Это привело бы, например, к тому, что клавиатура была бы заблокирована.

Еще одно замечание, касающееся обработки аппаратных прерываний. Если вы полностью заменяете стандартный обработчик аппаратного прерывания, не забудьте в конце программы выдать байт 20h в порт с адресом 20h (A0h для второго контроллера 8259). Эти действия необходимы для очистки регистра обслуживания прерывания ISR. При этом разрешается обработка прерываний с более низким приоритетом чем то, которое только что обрабатывалось.

Если вы обрабатываете прерывание 1Ch, то добавка в конце программы не нужна, так как это прерывание является расширением другого прерывания (прерывания таймера).

Перед тем, как завершить изучение прерываний, зададимся вопросом - можно ли замаскировать немаскируемое прерывание? Оказывается можно!

Конечно, если сигнал прерывания пришел на вход немаскируемого прерывания процессора, ничего сделать нельзя - прерывание произойдет неизбежно. Но в компьютерах XT и AT предусмотрены схемы, блокирующие вход немаскируемого прерывания процессора NMI.

Для XT маскированием немаскируемого прерывания управляет порт с адресом 0A0h. Если записать в него 0, немаскируемое прерывание будет запрещено, если 80h - разрешено.

Аналогично для AT маскированием немаскируемого прерывания управляет бит 7 порта 70h. Запись байта 0ADh в порт 70h запретит немаскируемое прерывание, а байта 2Dh - разрешит прохождение прерывания.

Заметим, что мы не запрещаем немаскируемое прерывание "внутри" процессора - это невозможно по определению, мы "не пускаем" сигнал прерывания на вход NMI.

Вектор прерывания

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

Таблица векторов прерываний

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

Организация вложенных прерываний

Возможна ситуация, когда в момент обработки первого прерывания приходит запрос на еще одно прерывание.

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

В системе установлены приоритетные соотношения между запросами прерываний.

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

Например, запрос на прерывание от таймера всегда приоритетнее запроса от любого внешнего устройства, а программы пользователя имеют самый низкий приоритет и могут быть прерваны чем угодно.

Существует понятие глубины прерывания - это максимальное число программ, которые могут прерывать друг друга. Если после перехода к прерывающей программе и вплоть до ее окончания прием других запросов запрещается, то говорят, что система имеет глубину прерывания, равную 1. Глубина равна n, если допускается последовательное прерывание до n программ. Системы с большим значением глубины прерывания обеспечивают более быструю реакцию на срочные запросы.

Различают использование абсолютных и относительных приоритетов.

Схема с абсолютными приоритетами:

Поступивший запрос с более высоким приоритетом, чем обрабатывающийся сейчас, прерывает выполняемую программу.

Схема с относительными приоритетами:

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

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

  • 5.Организация микропроцессорной системы (мпс): магистрально-модульный принцип организации мпс, основные классы микропроцессорных средств. Микропроцессорная система (мпс)
  • 6. Типовые структуры мпс: магистральная, магистрально-каскадная, магистрально-радиальная.
  • 7.Шинная организация микропроцессорных систем: с одной шиной, с двумя видами шин, с тремя видами шин.
  • 8. Характеристики микропроцессоров.
  • 9. Организация магистрали микропроцессорной системы. Трехшинная магистраль с раздельными шинами передачи адреса и данных.
  • 10. Циклы обращения к магистрали.
  • 11. Организация обращения к магистрали с синхронным доступом.
  • 12. Организация обращения к магистрали с асинхронным доступом.
  • 13. Совмещение адресной шины и шины данных. Двухшинная магистраль с совмещенными шинами адреса/данных.
  • 14. Механизм пакетной передачи данных по системной магистрали.
  • 15. Архитектура подсистемы памяти микропроцессорной системы. Характеристики подсистемы памяти микропроцессорной системы
  • 16. Адресная память (запоминающие устройства с произвольным доступом).
  • 17. Ассоциативная память.
  • 18. Стековая память.
  • 19. Основная память: блочная, циклическая и блочно-циклическая схемы организации основной памяти.
  • 20. Кэш-память. Принципы кэширования памяти.
  • 21. Способы отображения основной памяти на кэш-память. Архитектуры кэш-памяти.
  • 22.Алгоритмы замещения информации в заполненной кэш-памяти.
  • 23.Алгоритмы согласования содержимого кэш-памяти и основной памяти.
  • 24.Концепция виртуальной памяти.
  • 25.Страничная организация виртуальной памяти.
  • 26.Сегментная организация виртуальной памяти. Комбинированная сегментно- страничная организация виртуальной памяти.
  • 27.Архитектура подсистемы ввода/вывода микропроцессорной системы.
  • 28.Организация прерываний в микропроцессорной системе.
  • 29.Радиальная система прерываний.
  • 30. Векторная система прерываний.
  • 31.Организация прямого доступа к памяти в микропроцессорной системе.
  • 32.Аккумуляторная архитектура микропроцессоров.
  • 33.Регистровая архитектура микропроцессоров.
  • 34. Архитектура микропроцессоров с выделенным доступом к памяти.
  • 35.Стековая архитектура микропроцессоров.
  • 36.Классификация команд микропроцессоров.
  • 37.Структура (форматы) команд микропроцессоров.
  • 38. Регистровые структуры микропроцессоров
  • 39. Адресация данных в микропроцессорах: представление адресной информации, способы адресации.
  • 40.Управление памятью в микропроцессорах: линейная и сегментная адресации, преобразование логических адресов в физические, управление виртуальной памятью.
  • 41.Защита памяти в микропроцессорах: механизмы защиты, концепция привилегий.
  • 42.Поддержка операционной системы в микропроцессорах.
  • 43.Специальные прерывания (особые случаи, исключения) в микропроцессорах.
  • 44.Мультипрограммный режим работы микропроцессоров.
  • 45.Структурная организация однокристальных микроконтроллеров (на примере 8- разрядных микроконтроллеров): модульный принцип построения, типы процессорных ядер.
  • 46.Резидентная (внутренняя) память микроконтроллеров.
  • 47.Периферийные устройства микроконтроллеров: параллельные порты ввода/вывода, таймеры и процессоры событий, интерфейсы последовательного ввода/вывода.
  • 48.Основы организации интерфейсов микропроцессорных систем.
  • 49.Классификация интерфейсов.
  • 50.Организация параллельной передачи данных.
  • 51.Организация последовательной передачи данных.
  • 52.Основы проектирования микропроцессорных систем: цикл проектирования мпс, средства разработки и отладки мпс.
  • 30. Векторная система прерываний.

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

    Вектор прерывания может представлять собой:

    полную команду вызова подпрограммы вместе с адресом подпрограммы обработки прерывания;

    адрес подпрограммы обработки прерывания;

    указательна адрес подпрограммы обработки прерывания. В качествеуказатель может использоваться либо адрес, по которому в памяти хранится адрес подпрограммы обработки прерывания (иногда такой указатель называют адресом вектора прерывания), либо тип прерывания.

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

    При формировании вектора прерывания средствами ПУ логика работы программного поллингапереносится на аппаратные средства – определениенаиболее приоритетного запроса осуществляется с помощью аппаратного опроса готовности ПУ. Такой подход называется аппаратным поллингом . Линии запросов от всех ПУ объединяются по схеме «монтажное ИЛИ» и подключаются к общей линии запроса прерывания IRQ процессора (рис. 40).

    Рисунок 40 – Формирование вектора прерывания средствами ПУ

    Процессор при поступлении в него по линии IRQ запроса прерывания формирует управляющий сигнал подтверждения прерывания INTA, который поступает сначала в контроллер ближайшего к процессору ПУ. Если это ПУ нетребовало обслуживания, то его контроллер пропускает сигнал подтверждения прерывания на следующий контроллер, иначе дальнейшее распространение сигналапрекращается и контроллер выдает в шину данных вектор прерывания. Такая схема носит ярко выраженный шлейфовый характер. Одна линия подтверждения прерывания проходит последовательно через контроллеры ПУ и образует последовательную приоритетную структуру, называемую дейзи-цепочкой . Приоритет определяется физическим положением каждого ПУ. Ближайшее к процессору ПУ имеет наибольший приоритет.

    Дейзи-цепочка имеет двапреимущества. Во-первых, в системной магистрали нужнатолько одна линия запроса прерывания (одна линия запроса используетсяи в системе с программным опросом готовности ПУ, однако аппаратный опрос готовности ПУ производится гораздо быстрее). Во-вторых, в систему можно ввести новое ПУ с любым требуемым приоритетом, просто подключая его в нужную физическую позицию. Количество ПУ в системе ограничивается только числом векторов прерываний. Однако дейзи-цепочка медленнее параллельного способа, реализуемого в контроллере прерываний, так как сигнал подтверждения прерывания последовательно распространяется через каждое ПУ. Еще один недостаток шлейфовой структуры – трудность управления приоритетами. ПУ, стоящие в дейзи-цепочке ближе к процессору, обладают более высоким приоритетом, поэтому изменениеприоритетов требует изменения последовательности включения ПУ, что во многих случаях затруднительно. Наиболее эффективно векторная система прерываний реализуется с помощью контроллера прерываний (рис. 41)

    Рисунок 41 – Векторная система прерываний на основе контроллера прерываний

    Контроллер прерываний (КПР) может рассматриваться как расширение процессора, по этой причине его иногданазывают сопроцессором обработки прерываний. На основе КПР формируется многоуровневая приоритетная система векторных прерываний. КПР обеспечивает прием и обработку N запросов на прерывание. Приоритетная логика КПР выбирает из числа поступивших запросов на прерывание запрос с наивысшим приоритетом и сравнивает его с текущим приоритетом запроса, находящегося на обслуживании. При превышении текущего приоритета КПР генерирует сигнал запроса прерывания INT, который поступает в процессор. МП подтверждает прием запроса INTгенерацией сигнала подтверждение прерывания INTA, в ответ накоторый КПР выдает на шину данных системной магистрали соответствующий вектор прерывания. До тех пор, пока некоторый запрос находится в обслуживании, все запросы с равным или меньшим приоритетом игнорируются. В то же время запросы с более высоким приоритетом приводят к генерации сигнала INT, инициируя вложенные прерывания. Для оперативного управления работой контроллера предусматривается возможность его программирования, что позволяет динамически изменять приоритеты запросов, формируемые вектора прерываний и т.п.

    "

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

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

    Кажется очевидным, что возможны самые разнообразные прерывания по самым различным причинам. Поэтому с прерыванием связывают число - так называемый номер прерывания.

    Этот номер однозначно соответствует тому или иному событию. Система умеет распознавать прерывания и при их возникновении запускает процедуру, соответствующую номеру прерывания.

    Некоторые прерывания (первые пять по порядку номеров) зарезервированы для использования центральным процессором на случай каких-либо особых событий вроде попытки деления на нуль, переполнения и т. п.

    Программы могут сами вызывать прерывания с заданным номером. Для этого они используют команду INT. Это так называемые программные прерывания. Программные прерывания не являются асинхронными, так как вызываются из программы.

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

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

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

    Использование прерываний при работе с медленными внешними устройствами позволяют совместить ввод/вывод с обработкой данных в центральном процессоре. В результате этого повышается общая производительность системы.

    Иногда желательно сделать систему нечувствительной ко всем или отдельным аппаратным прерываниям. Для этого используют так называемое маскирование прерываний, о котором мы еще будем говорить. Но существует и немаскируемое прерывание (которое, кстати, все-таки можно замаскировать, или, точнее говоря, заблокировать).

    Заметим, что обработчики прерываний могут сами вызывать программные прерывания, например, для получения доступа к сервису BIOS или MS-DOS.

    Составление собственных программ обработки прерываний и замена стандартных обработчиков MS-DOS и BIOS является достаточно сложной задачей. Необходимо учитывать все тонкости работы аппаратуры, а также взаимодействия программного и аппаратного обеспечения. При отладке возможно разрушение операционной системы с непредсказуемыми последствиями, поэтому надо очень внимательно следить за тем, что делает ваша программа.

    4.1. Таблица векторов прерываний

    Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти. Эта таблица находится в диапазоне адресов от 0000:0000 до 0000:03FFh и состоит из 256 элементов - дальних адресов обработчиков прерываний.

    Элементы таблицы векторов прерываний называются векторами прерываний. В первом слове элемента таблицы записана компонента смещения, а во втором - сегментная компонента адреса обработчика прерывания.

    Вектор прерывания с номером 0 находится по адресу 0000:0000, с номером 1 - по адресу 0000:0004 и т. д.

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

    void (far* interrupt_table)();

    Инициализация таблицы выполняется частично системой базового ввода/вывода BIOS после тестирования аппаратуры и перед началом загрузки операционной системой, частично при загрузке MS-DOS. Операционная система MS-DOS может изменить некоторые вектора прерываний, установленные BIOS.

    Расскажем о назначении наиболее важных векторов прерываний.

    Номер Описание
    0 Ошибка деления.Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). Обычно при обработке этого прерывания MS-DOS выводит сообщение об ошибке и останавливает выполнение программы. При этом для процессора i8086 адрес возврата указывает на команду, следующую после команды деления, а для процессора i80286 и более старших моделей - на первый байт команды, вызвавшей прерывание
    1 Прерывание пошагового режима.Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после пересылки данных в сегментные регистры командами MOV и POP
    2 Аппаратное немаскируемое прерывание.Это прерывание может использоваться по-разному в разных машинах. Обычно оно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора
    3 Прерывание для трассировки.Генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания
    4 Переполнение. Генерируется машинной командой INTO , если установлен флаг переполнения OF. Если флаг не установлен, команда INTO выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций
    5 Печать копии экрана. Генерируется, если пользователь нажал клавишу В программах MS-DOS обычно используется для печати образа экрана. Для процессора i80286 и более старших моделей генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона
    6 Неопределенный код операции или длина команды больше 10 байт
    7 Особый случай отсутствия арифметического сопроцессора
    8
    9 IRQ1 - прерывание от клавиатуры. Генерируется, когда пользователь нажимает и отжимает клавиши. Используется для чтения данных из клавиатуры
    A
    B
    C
    D IRQ5 - прерывание от контроллера жесткого диска (только для компьютеров IBM PC/XT)
    E IRQ6 - прерывание генерируется контроллером НГМД после завершения операции ввода/вывода
    F IRQ7 - прерывание от параллельного адаптера. Генерируется, когда подключенный к адаптеру принтер готов к выполнению очередной операции. Обычно не используется
    10 Обслуживание видеоадаптера
    11 Определение конфигурации устройств в системе
    12 Определение размера оперативной памяти
    13 Обслуживание дисковой системы
    14 Работа с асинхронным последовательным адаптером
    15 Расширенный сервис
    16 Обслуживание клавиатуры
    17 Обслуживание принтера
    18 Запуск BASIC в ПЗУ, если он есть
    1A Обслуживание часов
    1B Обработчик прерывания, возникающего, если пользователь нажал комбинацию клавиш
    1C Программное прерывание, вызывается 18,2 раза в секунду обработчиком аппаратного прерывания таймера
    1D Адрес видеотаблицы для контроллера видеоадаптера 6845
    1E Указатель на таблицу параметров дискеты
    1F Указатель на графическую таблицу для символов с кодами ASCII 128-255
    20-5F Используется MS-DOS или зарезервировано для MS-DOS
    60-67 Прерывания, зарезервированные для программ пользователя
    68-6F Не используются
    70
    71
    72 IRQ10 - зарезервировано
    73 IRQ11 - зарезервировано
    74 IRQ12 - зарезервировано
    75
    76
    77 IRQ15 - зарезервировано
    78 - 7F Не используются
    80-85 Зарезервировано для BASIC
    86-F0 Используются интерпретатором BASIC
    F1-FF Не используются

    Прерывания, обозначенные как IRQ0 - IRQ15 являются аппаратными прерываниями.

    4.2. Маскирование прерываний

    Часто при выполнении критических участков программ приходится запрещать прерывания для того чтобы гарантировать непрерываемое выполнение определенной последовательности команд. Это можно сделать командой CLI. Ее нужно поместить в начало критической последовательности команд, а в конце расположить команду STI, разрешающую процессору воспринимать прерывания. Команда CLI запрещает только маскируемые прерывания, на обработку немаскируемого прерывания эта команда никакого влияния не оказывает.

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

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

    4.3. Изменение таблицы векторов прерываний

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

    Очень важно не забыть перед завершением работы восстановить содержимое измененных векторов в таблице прерываний.

    Дело в том, что память, которая была распределена программе, после завершения работы программы освобождается. Она может быть использована, например, для загрузки другой программы. Если вы забыли восстановить вектор и пришло прерывание, то система может разрушиться - вектор теперь указывает на область, которая может содержать что угодно.

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

    • прочитать содержимое элемента таблицы векторов прерываний для вектора с нужным вам номером;
    • запомнить это содержимое (адрес старого обработчика прерывания) в области данных программы;
    • установить новый адрес в таблице векторов прерываний так, чтобы он указывал на начало вашей программы обработки прерывания;
    • перед завершением работы программы прочитать из области данных адрес старого обработчика прерывания и записать его в таблицу векторов прерываний.

    Кроме того, операция изменения вектора прерывания должна быть непрерывной в том смысле, что во время изменения не должно произойти прерывание. Если вы, например, запишете новое значение смещения, а сегментный адрес обновить не успеете, то по какому адресу будет передано управление в случае прерывания и что при этом произойдет? Об этом можно только догадываться.

    Функции MS-DOS для работы с таблицей прерываний

    Для облегчения работы по замене векторов прерываний MS-DOS предоставляет в ваше распоряжение специальные функции, предназначенные для чтения элемента таблицы векторов прерывания и для записи в нее нового адреса. Если вы будете использовать эти функции, MS-DOS гарантирует, что операция по замене вектора будет выполнена правильно. Вам не надо заботиться о непрерывности процесса замены вектора прерывания.

    Для чтения вектора используйте функцию 35h прерывания INT 21h . Перед ее вызовом регистр AL должен содержать номер вектора в таблице. После выполнения функции в регистрах ES:BX будет искомый адрес обработчика прерывания.

    Для вектора с номером, находящимся в регистре AL, функция 25h прерывания INT 21h устанавливает новый обработчик прерывания. Адрес обработчика прерываний следует передать через регистры DS:DX.

    Разумеется, вы можете также обращаться к таблице векторов прерываний непосредственно, но тогда при записи необходимо замаскировать прерывания командой CLI, не забыв разрешить их после записи командой STI.

    Пользователям языка С доступны функции _dos_getvect и _dos_setvect . Первая функция получает адрес из таблицы векторов прерываний, вторая устанавливает новый адрес. Обе эти функции обращаются к описанным выше функциям 35h и 25h прерывания INT 21h .

    Какие требования предъявляются к программе обработки прерывания?

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

    Цепочки обработчиков прерываний

    Если вам надо добавить какие-либо собственные действия к тем, что выполняет стандартный обработчик прерывания, то можно организовать цепочку прерываний.

    Для организации цепочки прерываний нужно записать в векторную таблицу адрес своего обработчика, не забыв сохранить прежнее содержимое таблицы. Ваш обработчик получает управление по прерыванию, выполняет какие-либо действия, затем передает управление старому обработчику.

    Можно сделать и по-другому: ваш обработчик вызывает старый обработчик как подпрограмму, а затем после возврата из старого обработчика выполняет дополнительные действия. Иными словами, вы можете вставить дополнительную обработку как до вызова старого обработчика, так и после его вызова.

    В библиотеке транслятора C имеется функция для организации цепочки прерываний с именем _chain_intr .

    Для описания функции, выполняющей роль обработчика прерывания, следует использовать ключевое слово interrupt.

    Такая функция завершается командой возврата из обработки прерывания IRET. Для нее автоматически генерируются команды сохранения регистров на входе и их восстановления при выходе из обработчика прерывания. Пример использования ключевого слова interrupt для определения функции обработки прерывания:

    void interrupt far int_funct(...) { // Тело обработчика прерывания }

    Функция обработки прерывания должна быть дальней функцией, так как таблица векторов прерываний содержит полные адреса в формате <сегмент:смещение>.

    Ключевое слово interrupt используется также для описания переменных, предназначенных для хранения векторов прерываний:

    void (interrupt (far *oldvect)(...);

    Для установки своего обработчика прерываний используйте функцию _dos_setvec . Эта функция имеет два параметра - номер прерывания и указатель на новую функцию обработки прерывания.

    Например:

    _dos_setvect (0x16, my_key_intr);

    В этом примере для прерывания с номером 16h (программное прерывание, предназначенное для чтения данных из клавиатуры) устанавливается новый обработчик прерывания my_key_intr.

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

    Например:

    old_vector = _dos_getvect (0x16);

    Для организации цепочки прерываний используйте функцию _chain_intr . В качестве параметра эта функция принимает адрес старого обработчика прерываний.

    Программа BEEPER

    Программа BEEPER (листинг 4.1) - простой пример, который иллюстрирует применение всех трех перечисленных выше функций, предназначенных для работы с прерываниями.

    Листинг 4.1. Файл beeper\beeper.cpp

    #include #include #include void main(void); void interrupt far timer(...); void interrupt (far *oldvect)(...); // Переменная для подсчета прерываний таймера volatile long ticks; void main(void) { // Сбрасываем счетчик ticks = 0L; // Запоминаем адрес старого обработчика // прерывания oldvect = _dos_getvect (0x1c); // Устанавливаем новый обработчик прерывания _dos_setvect (0x1c, timer); printf("\nТаймер установлен. Нажмите любую" " клавишу...\n"); getch(); // Восстанавливаем старый обработчик прерывания _dos_setvect (0x1c,oldvect); } void interrupt far timer(...) { // Увеличиваем счетчик прерываний таймера ticks++; // Если значение счетчика кратно 20, // выдаем сигнал на громкоговоритель компьютера if((ticks % 20) == 0) { asm mov bx,0 asm mov ax, 0E07h asm int 10h } // Вызываем старый обработчик прерывания _chain_intr (oldvect); }

    Эта программа встраивает собственный обработчик прерывания таймера, который будет вызываться примерно 18,2 раза в секунду. Встраиваемый обработчик прерывания подсчитывает прерывания таймера и, если значение соответствующего счетчика кратно 20, громкоговоритель компьютера издает звуковой сигнал.

    В конце работы новая программа обработки прерывания таймера вызывает старый обработчик с помощью функции _chain_intr .

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

    4.4. Особенности обработки аппаратных прерываний

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

    В отличие от программных прерываний, вызываемых запланировано программой или драйвером, аппаратные прерывания всегда происходят асинхронно по отношению к выполняющимся программам. Кроме того, может возникнуть одновременно сразу несколько прерываний!

    Для того чтобы система "не растерялась", решая какое прерывание обслуживать в первую очередь, существует специальная схема приоритетов. Каждому прерыванию назначается свой приоритет. Если происходит одновременно несколько прерываний, система отдает предпочтение самому высокоприоритетному, откладывая на время обработку остальных прерываний.

    Система приоритетов реализована на двух микросхемах Intel 8259 (или аналогичных). Каждая микросхема является контроллером прерывания и обслуживает до восьми приоритетов. Микросхемы можно объединять (каскадировать) для увеличения количества уровней приоритетов в системе.

    Уровни приоритетов обозначаются сокращенно IRQ0 - IRQ15 .

    В компьютере типа IBM PC/XT была установлена только одна микросхема контроллера прерывания. Приоритеты линейно зависели от номера уровня прерывания. Прерывание IRQ0 соответствовало самому высокому приоритету, за ним шли прерывания IRQ1 , IRQ2 , IRQ3 и так далее.

    Прерывание IRQ2 в компьютерах IBM PC/XT было зарезервировано для дальнейшего расширения системы. В компьютерах IBM PC/AT прерывание IRQ2 стало использоваться для каскадирования двух контроллеров прерывания 8259. Добавленные приоритетные уровни прерываний IRQ8 - IRQ15 в этих компьютерах располагаются по приоритету между прерываниями IRQ1 и IRQ3 .

    Приведем список аппаратных прерываний, расположенных в порядке убывания приоритета:

    Номер Описание
    8 IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду
    9 IRQ1 - прерывание от клавиатуры
    A IRQ2 - используется для каскадирования аппаратных прерываний
    70 IRQ8 - прерывание от часов реального времени
    71 IRQ9 - прерывание от контроллера EGA
    72 IRQ10 - зарезервировано
    73 IRQ11 - зарезервировано
    74 IRQ12 - зарезервировано
    75 IRQ13 - прерывание от арифметического сопроцессора
    76 IRQ14 - прерывание от контроллера жесткого диска
    77 IRQ15 - зарезервировано
    B IRQ3 - прерывание асинхронного порта COM2
    C IRQ4 - прерывание асинхронного порта COM1
    D IRQ5 - прерывание от контроллера жесткого диска (только в компьютерах IBM PC/XT)
    E IRQ6 - прерывание генерируется контроллером НГМД
    F IRQ7 - прерывание принтера

    Из этого списка видно, что самый высокий приоритет у прерываний от интервального таймера, затем идет прерывание от клавиатуры. Наименьший приоритет имеет прерывание принтера.

    Для управления схемами приоритетов необходимо знать внутреннее устройство контроллера прерываний 8259.

    Поступающие прерывания запоминаются в регистре запроса на прерывание IRR. Каждый бит из восьми в этом регистре соответствует своему прерыванию.

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

    Наиболее интересными с точки зрения программирования контроллера прерываний являются регистры маски прерываний IMR и управляющий регистр прерываний.

    В компьютерах IBM PC/XT регистр маски прерываний имеет адрес 21h, управляющий регистр прерываний - 20h. В компьютерах IBM PC/AT первый контроллер 8259 имеет такие же адреса, что и в IBM PC/XT. Регистр маски прерываний второго контроллера имеет адрес A1h, управляющий регистр прерываний - адрес A0h.

    Разряды регистра маски прерываний соответствуют номерам IRQ. Для того чтобы замаскировать аппаратное прерывание какого-либо уровня, надо записать в регистр маски байт масок. В этом байте следует установить в 1 те биты, которые соответствуют маскируемым прерываниям. Например, для маскирования прерываний от НГМД в порт 21h надо записать двоичное число 01000000.

    Приведем строку программы, маскирующей прерывание от флоппи-диска:

    outp(0x21, 0x40);

    Чтобы "оживить" прерывания от НГМД, используйте следующую строку (которая размаскирует все прерывания):

    outp(0x21, 0);

    Заметьте, что в приведенном выше примере мы замаскировали прерывание именно от НГМД, все остальные устройства продолжали нормально работать. Если бы мы выдали машинную команду CLI, то отключились бы все аппаратные прерывания. Это привело бы, например, к тому, что клавиатура была бы заблокирована.

    Еще одно замечание, касающееся обработки аппаратных прерываний.

    Если вы полностью заменяете стандартный обработчик аппаратного прерывания, не забудьте в конце программы записать байт 20h в порт с адресом 20h (A0h для второго контроллера 8259). Эти действия необходимы для очистки регистра обслуживания прерывания ISR. При этом разрешается обработка прерываний с более низким приоритетом чем то, которое только что обрабатывалось.

    Если вы обрабатываете прерывание 1Ch, то указанная выше добавка в конце программы обработки прерывания не нужна, так как это прерывание является программным и вызывается из обработчика аппаратного прерывания таймера.

    Перед тем как завершить изучение прерываний, зададимся вопросом - можно ли замаскировать немаскируемое прерывание? Оказывается можно!

    Конечно, если сигнал прерывания пришел на вход немаскируемого прерывания процессора, ничего сделать нельзя - прерывание произойдет неизбежно. Но в компьютере предусмотрены схемы, блокирующие вход немаскируемого прерывания процессора NMI.

    Для компьютера IBM PC/XT маскированием немаскируемого прерывания управляет порт с адресом 0A0h. Если записать в него 0, немаскируемое прерывание будет запрещено, если 80h - разрешено.

    Аналогично для IBM PC/AT маскированием немаскируемого прерывания управляет бит 7 порта 70h. Запись байта 0ADh в порт 70h запретит немаскируемое прерывание, а байта 2Dh - разрешит прохождение прерывания.

    Заметим, что мы не запрещаем немаскируемое прерывание "внутри" процессора - это невозможно по определению, мы "не пускаем" сигнал прерывания на вход NMI.

    Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти - адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов - FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний. В первом слове элемента таблицы записано смещение, а во втором - адрес сегмента обработчика прерывания.

    Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с номером 1 - 0000:0004 и т.д. Для программиста, использующего язык Си, таблицу можно описать следующим образом:

    void (* interrupt_table)();

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

    В таблице 5.1. приведено назначение некоторых наиболее важных векторов.

    Таблица 5.1.

    Описание

    Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). DOS обычно при обработке этого прерывания выводит сообщение об ошибке и останавливает выполнение программы. Для процессора 8086 при этом адрес возврата указывает на следующую после команды деления команду, а в более поздних процессорах - на первый байт команды, вызвавшей прерывание.

    Прерывание пошагового режима. Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после выполнения команды MOV в сегментные регистры или после загрузки сегментных регистров командой POP.

    Аппаратное немаскируемое прерывание. Это прерывание может использоваться по-разному в разных машинах. Обычно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора.

    Прерывание для трассировки. Это прерывание генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания.

    Переполнение. Генерируется машинной командой INT0, если установлен флаг 0F. Если флаг не установлен, то команда INT0 выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций.

    Печать копии экрана. Генерируется при нажатии на клавиатуре клавиши PrtScr. Обычно используется для печати образа экрана. Для процессора 80286 генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона.

    Неопределенный код операции или длина команды больше 10 байт (для процессора 80286).

    Особый случай отсутствия математического сопроцессора (процессор 80286).

    IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду.

    IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных от клавиатуры.

    IRQ2 - используется для каскадирования аппаратных прерываний в машинах класса AT.

    IRQ3 - прерывание асинхронного порта COM2.

    IRQ4 - прерывание асинхронного порта COM1.

    IRQ5 - прерывание от контроллера жесткого диска для XT.

    IRQ6 - прерывание генерируется контроллером флоппи-диска после завершения операции.

    IRQ7 - прерывание принтера. Генерируется принтером, когда он готов к выполнению очередной операции. Многие адаптеры принтера не используют это прерывание.

    Обслуживание видеоадаптера.

    Определение конфигурации устройств в системе.

    Определение размера оперативной памяти в системе.

    Обслуживание дисковой системы.

    Последовательный ввод/вывод.

    Расширенный сервис для AT-компьютеров.

    Обслуживание клавиатуры.

    Обслуживание принтера.

    Запуск BASIC в ПЗУ, если он есть.

    Обслуживание часов.

    Обработчик прерывания Ctrl-Break.

    Прерывание возникает 18.2 раза в секунду, вызывается программно обработчиком прерывания таймера.

    Адрес видеотаблицы для контроллера видеоадаптера 6845.

    Указатель на таблицу параметров дискеты.

    Указатель на графическую таблицу для символов с кодами ASCII 128-255.

    Используется DOS или зарезервировано для DOS.

    Прерывания, зарезервированные для пользователя.

    Не используются.

    IRQ8 - прерывание от часов реального времени.

    IRQ9 - прерывание от контроллера EGA.

    IRQ10 - зарезервировано.

    IRQ11 - зарезервировано.

    IRQ12 - зарезервировано.

    IRQ13 - прерывание от математического сопроцессора.

    IRQ14 - прерывание от контроллера жесткого диска.

    IRQ15 - зарезервировано.

    Не используются.

    Зарезервированы для BASIC.

    Используются интерпретатором BASIC.

    Не используются.

    IRQ0 - IRQ15 - это аппаратные прерывания, о них будет рассказано позже.

    Загрузка...
    Top