Прерывания векторы программных и аппаратных прерываний. AVR. Учебный Курс. Управляемый вектор прерывания. Особенности обработки аппаратных прерываний

Таблица векторов Cortex начинается с нижней части адресного пространства. Однако таблица векторов начинается не с нулевого адреса. а с адреса 0x00000004, т. к. первые четыре байта используются для хранения начального адреса указателя стека. Таблица векторов исключительных ситуаций содержит адреса, которые загружаются в счетчик программы, когда микропроцессор переходит в исключительную ситуацию.

Каждый из векторов прерываний занимает 4 байта и указывает на начальный адрес каждой конкретной процедуры обработки прерывания. Первые 15 векторов - адреса обработки исключительных ситуаций, возникающих в ядре Cortex. К ним относятся вектор сброса, немаскируемое прерывание, управление авариями и ошибками, исключительные ситуации отладочной системы и прерывание таймера SysTick. Набор инструкций Thumb-2 также поддерживает инструкцию. выполнение которой приводит к генерации исключительной ситуации. Начиная с 16 вектора, следуют адреса обработки прерываний пользовательских У ВВ. Их назначение зависит от каждого конкретного производителя. В программе таблица векторов обычно приводится в отдельном файле и содержит адреса процедур обработки прерываний (рис. 1.7).

Рис. 1.7.

Например, если используется прерывание таймера SysTick, то объявление на Си процедуры обработки прерывания выполняется следующим образом (рис. 1.8).

Рис. 1.8.

Теперь, когда сконфигурирована таблица векторов и объявлена процедура обработки прерываний, мы можем настроить NV1C на обработку прерывания таймера SysTick. Обычно для этого выполняют две операции: задается приоритет прерывания, а затем разрешается источник прерывания. Регистры NVIC расположены в области системных ресурсов Cortex-МЗ, и доступ к ним возможен при работе микропроцессора только в привилегированном режиме.

Настройка внутренних исключительных ситуаций процессора выполняется с помощью регистров системного управления и системных приоритетов, а пользовательских УВВ - с помощью регистров IRQ. Прерывание SysTick является внутренней исключительной ситуацией процессора Cortex и поэтому управляется через системные регистры. Некоторые внутренние исключительные ситуации постоянно разрешены. К ним относятся прерывание по сбросу, немаскированное прерывание, а также прерывание таймера SysTick, поэтому никаких действий с NVIC по разрешению этого прерывания делать не нужно. Для настройки прерывания SysTick нам необходимо активизировать сам таймер и его прерывание с помощью соответствующего регистра управления.

Приоритет каждой внутренней исключительной ситуации Cortex можно задать в системных регистрах приоритета. У исключительных ситуаций Reset, NMI и hard fault он фиксированный. Этим гарантируется, что ядро всегда будет переходить к обработке известной исключительной ситуации. У всех остальных исключительных ситуаций имеется восьмибитное поле, которое расположено в трех системных регистрах приоритета. Микроконтроллеры STM32 используют только 16 уровней приоритета, поэтому у них активны только 4 бита этого поля. Однако важно запомнить, что приоритет устанавливается четырьмя старшими битами.

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

У каждого источника прерывания имеется бит разрешения, как в NVIC, так и в УВВ. У микроконтроллера STM32 используется 16 уровней приоритетов. Всего предусмотрено 16 регистров приоритета. Каждый из них разделен на четыре 8-битных поля для задания приоритета. Каждое поле связано с конкретным вектором прерывания. У микроконтроллера STM32 используется только половина такого поля, т. к. реализовано только 16 уровней приоритета. Однако необходимо помнить, что активные биты приоритета находятся в старшей тетраде поля. По умолчанию поле приоритета определяет 16 уровней приоритета, причем уровень 0 - высший приоритет, а 15 - низший. Поле приоритета также можно представить в виде групп и подгрупп приоритета. Это не добавляет дополнительных уровней приоритета, просто облегчает управление ими при необходимости задания в поле

PRIGROUP регистра прикладных прерываний и управления сбросом большого числа прерываний. Поле PRIGROUP разделяет уровни приоритетов на группы и подгруппы. Это необходимо для повышения программной абстракции при работе с большим числом прерываний. Трехбитное поле PRIGROUP управляет разделением 4-битных полей приоритета на группы и подгруппы. Например, запись в PRIGROUP числа 3 приведет к созданию двух групп с 4 уровнями приоритетов в каждой. После этого вы можете в программе выполнить определения высокоприоритетной и низкоприоритетной групп прерываний. В рамках каждой группы можно задавать подуровни, в т. ч. низкий, средний, высокий и очень высокий. Ранее уже говорилось, что это позволяет более абстрактно смотреть на структуру прерываний и помогает программисту управлять большим числом прерываний. Конфигурация прерываний УВВ очень похожа на конфигурацию внутренних исключительных ситуаций процессора Cortex.

  • 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, инициируя вложенные прерывания. Для оперативного управления работой контроллера предусматривается возможность его программирования, что позволяет динамически изменять приоритеты запросов, формируемые вектора прерываний и т.п.

    "

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

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

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

    Конечно, можно добавить в обработчик прерывания switch-case конструкцию и по выбору режима перейти на нужный участок кода, но это довольно громоздко, а самое главное — время перехода будет разное, в зависимости от того в каком порядке будет идти опрос-сравнение switch-case структуры.

    То есть в свитче вида:

    1 2 3 4 5 6 7 switch (x) { 1 : Действие 1 2 : Действие 2 3 : Действие 3 4 : Действие 4 }

    switch(x) { 1: Действие 1 2: Действие 2 3: Действие 3 4: Действие 4 }

    Будет последовательное сравнение х вначале с 1, потом с 2, потом с 3 и так до перебора всех вариантов. А в таком случае реакция на Действие 1 будет быстрей чем реакция на Действие 4. Особо важно это при расчете точных временных интервалов на таймере.

    Но есть простое решение этой проблемы — индексный переход. Достаточно перед тем как мы начнем ожидать прерывание предварительно загрузить в переменные (а можно и сразу в индексный регистр Z) направление куда нам надо перенаправить наш вектор и воткнуть в обработчик прерывания индексный переход. И вуаля! Переход будет туда куда нужно, без всякого сравнения вариантов.

    В памяти создаем переменные под плавающий вектор:

    Timer0_Vect_L: .byte 1 ; Два байта адреса, старший и младший Timer0_Vect_H: .byte 1

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

    CLI ; Критическая часть. Прерывания OFF LDI R16,low(Timer_01) ; Берем адрес и сохраняем STS Timer0_Vect_L,R16 ; его в ячейку памяти. LDI R16,High(Timer_01) ; Аналогично, но уже со старшим вектором STS Timer0_Vect_H,R16 SEI ; Прерывания ON

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

    А обработчик получается вида:

    1 2 3 4 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 46 47 48 49 50 ;============================= ; Вход в прерывание по переполнению от Timer0 ;============================= TIMER_0: PUSH ZL ; сохраняем индексный регистр в стек PUSH ZH ; т.к. мы его используем PUSH R2 ; сохраняем R2, т.к. мы его тоже портим IN R2,SREG ; Извлекем и сохраняем флаговый регистр PUSH R2 ; Если не сделать это, то 100% получим глюки LDS ZL,Timer0_Vect_L ; загружаем адрес нового вектора LDS ZH,Timer0_Vect_H ; оба байта. CLR R2 ; Очищаем R2 OR R2,ZL ; Проверяем вектор на ноль. Иначе схватим аналог OR R2,ZH ; reset"a. Проверка идет через операцию OR BREQ Exit_Tm0 ; с накоплением результата в R2 ; так мы не портим содержимое Z и нам не придется; загружать его снова IJMP ; Уходим по новому вектору; Выход из прерывания. Exit_Tm0: POP R2 ; Достаем и восстанавливаем регистр флагов OUT SREG,R2 POP R2 ; восстанавливаем R2 POP ZH ; Восстанавливаем Z POP ZL RETI ; Дополнительный вектор 1 Timer_01: NOP ; Это наши новые вектора NOP ; тут мы можем творить что угодно NOP ; желательно недолго - в прерывании же NOP ; как никак. Если используем какие другие NOP ; регистры, то их тоже в стеке сохраняем RJMP Exit_Tm0 ; Это переход на выход из прерывания; специально сделал через RJMP чтобы; Дополнительный вектор 2 ; сэкономить десяток байт на коде возврата:))) Timer_02: NOP NOP NOP NOP NOP RJMP Exit_Tm0 ; Дополнительный вектор 3 Timer_03: NOP NOP NOP NOP NOP RJMP Exit_Tm0

    ;============================= ; Вход в прерывание по переполнению от Timer0 ;============================= TIMER_0: PUSH ZL ; сохраняем индексный регистр в стек PUSH ZH ; т.к. мы его используем PUSH R2 ; сохраняем R2, т.к. мы его тоже портим IN R2,SREG ; Извлекем и сохраняем флаговый регистр PUSH R2 ; Если не сделать это, то 100% получим глюки LDS ZL,Timer0_Vect_L ; загружаем адрес нового вектора LDS ZH,Timer0_Vect_H ; оба байта. CLR R2 ; Очищаем R2 OR R2,ZL ; Проверяем вектор на ноль. Иначе схватим аналог OR R2,ZH ; reset"a. Проверка идет через операцию OR BREQ Exit_Tm0 ; с накоплением результата в R2 ; так мы не портим содержимое Z и нам не придется; загружать его снова IJMP ; Уходим по новому вектору; Выход из прерывания. Exit_Tm0: POP R2 ; Достаем и восстанавливаем регистр флагов OUT SREG,R2 POP R2 ; восстанавливаем R2 POP ZH ; Восстанавливаем Z POP ZL RETI ; Дополнительный вектор 1 Timer_01: NOP ; Это наши новые вектора NOP ; тут мы можем творить что угодно NOP ; желательно недолго - в прерывании же NOP ; как никак. Если используем какие другие NOP ; регистры, то их тоже в стеке сохраняем RJMP Exit_Tm0 ; Это переход на выход из прерывания; специально сделал через RJMP чтобы; Дополнительный вектор 2 ; сэкономить десяток байт на коде возврата:))) Timer_02: NOP NOP NOP NOP NOP RJMP Exit_Tm0 ; Дополнительный вектор 3 Timer_03: NOP NOP NOP NOP NOP RJMP Exit_Tm0

    Реализация для RTOS
    Но что делать если у нас программа построена так, что весь код вращается по цепочкам задач через диспетчер RTOS? Просчитать в уме как эти цепочки выполняются относительно друг друга очень сложно. И каждая из них может попытаться завладеть таймером (конечно не самовольно, с нашей подачи, мы же программу пишем, но отследить по времени как все будет сложно).
    В современных больших осях на этот случай есть механизм Mutual exclusion — mutex. Т.е. это своего рода флаг занятости. Если какой нибудь процесс общается, например, с UART то другой процесс туда байт сунуть не смеет и покорно ждет пока первый процесс освободит UART, о чем просемафорит флажок.

    В моей механизмов взаимоисключений нет, но их можно реализовать. По крайней мере сделать некоторое минимальное подобие. Полноценную реализацию всего этого барахла я делать не хочу, т.к. моей целью является удержания размера ядра на уровне 500-800 байт.
    Проще всего зарезервировать в памяти еще один байт — переменную занятости. И когда один процесс захватывает ресурс, то в эту переменную он записывает время когда ориентировочно он его освободит. Время идет в тиках системного таймера которое у меня 1ms.
    Если какой либо другой процесс попытается обратиться к этому же аппаратному ресурсу, то он вначале посмотрит на состояние его занятости, считает время в течении которого будет занято и уйдет покурить на этот период — загрузит сам себя в очередь по таймеру. Там снова проверит и так далее. Это простейший вариант.

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

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

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

    Разумеется таймер тут приведен для примера, большую часть задач можно решить системным таймером RTOS, но если нужна вдруг меньшая дискретность или высокая скорость реакции на событие (а не пока главный конвеер дотащит задачу до исполнения), то механим управляемых прерываний, ИМХО, то что доктор прописал.

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

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

    Таблица векторов прерываний располагается в самом начале ОП, т.е. её физический адрес = 0. Таблица векторов прерываний состоит из 256 элементов по 4 байта. Вектора состоят из 16 битового сегментного адреса и 16 битового смещения (сначала идет смещение, а потом сегмент). Каждый вектор прерываний имеет свой номер, называемый номером прерывания, который указывает на его место в таблице. Этот номер, умноженный на 4, дает абсолютный адрес вектора памяти.

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

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

    Перед входом в процедуру обработки прерываний принудительно сьрасывется флаг трассировки TF и флаг разрешения прерываний IF. Завершив обработку прерывания, процедура должна выдать команду IRET, по которой из стека будут извлечены значения регистров CS:IP и регистра флагов. Далее продолжается выполнение прерванной программы.

    Процедура обработки прерывания обязательно должна закончится процедурой IRET, после которой считываются значения flags, CS, IP.

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

    В общем случае все эти ситуации разделяются по принципу их обнаружения, источника возникновения и реакции на них на следующие три категории:

    • Прерывания и особые ситуации (Interrupts and Exceptions ) — обнаруживаются и обрабатываются процессором в самые различные моменты времени и могут происходить как из внешних так и из внутренних источников, все другие типы экстраординарных ситуаций занимают более низкий уровень иерархии и могут обрабатываться, только если сперва заявят о своем существовании через прерывание или особую ситуацию.
    • Исключительные ситуации FPU (Floating-Point Exceptions команд сопроцессора , команд MMX или 3DNow!-команд . Возникновение исключительной ситуации FPU , в свою очередь, может вызывать генерацию прерывания через подачу сигнала на специальные внешние выводы процессора (так называемая реакция в стиле MS-DOS ) или особой ситуации (внутренний механизм процессора обеспечивает генерацию ошибки сопроцессора #MF), обработчик которой далее сам разбирается с тем, какое исключение произошло и какие действия в связи с этим следует предпринять ().
    • Исключительные ситуации SIMD (SSE) (SIMD Floating-Point Exceptions ) — могут возникать только при выполнении SIMD-команд и полностью определяются состоянием SIMD-регистров процессора. SIMD-исключения сообщают о своем возникновении через генерацию специальной особой ситуации #XM . Получив управление, обработчик особой ситуации должен сам программным путем определить причину возникновения исключения ().

    Прерывания и особые ситуации

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

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

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

    Любые команды, для которых могут генерироваться особые ситуации , маскируемые и немаскируемые прерывания

    Любые невыровненные ссылки на данные в памяти, если активирован контроль выравнивания (CR0.AM = 1, EFLAGS.AC = 1, CPL = 3)

    Типы особых ситуаций и особенности их обработки

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

    • Ошибка (Fault ) — это особая ситуация , которая может быть исправлена обработчиком особой ситуации . При встрече ошибки состояние процессора сохраняется в том виде, каким оно было до начала выполнения команды, инициировавшей генерацию ошибки, а значения CS:EIP , указывающие на эту команду сохраняются в стеке обработчика. Прерванная программа после исправления ошибки может быть продолжена непосредственно с команды, вызвавшей эту ошибку .
    • Ловушка (Trap ) — особая ситуация , которая генерируется после выполнения соответствующей команды. В этом случае сохраняемые в стеке значения CS:EIP , указывают на команду, которая будет выполняться вслед за командой, вызвавшей ловушку ; например, если ловушка произошла во время команды JMP , то сохраненные значения CS:EIP указывают на команду, являвшуюся целью команды JMP .
    • Сбой (Abort ) — это особая ситуация , которая не допускает точную локализацию вызвавшей ее команды и не допускает перезапуска. Сбои используются для сообщений о некоторых ошибках, таких как: технические неисправности и наличие некорректных значений в системных таблицах.

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

    • таблица дескрипторов прерываний IDT (в режиме реальной адресации — таблица векторов прерываний IVT);
    • регистр таблицы дескрипторов прерываний IDTR ;
    • флаг маскирования внешних прерываний EFLAGS.IF ;
    • флаги для работы с виртуальными прерываниями EFLAGS.VIF , EFLAGS.VIP ;
    • специальная таблица — карта перенаправления прерываний IRB — располагается в сегменте TSS задачи;
    • специальные типы дескрипторов шлюзов .