Таблица дескрипторов прерываний (IDT ) - это структура данных, используемая архитектурой x86 для реализовать таблицу векторов прерываний. IDT используется процессором для определения правильного ответа на прерывания и исключения.
Подробности в описании ниже относятся конкретно к архитектуре x86 и архитектуре AMD64.. Другие архитектуры имеют похожие структуры данных, но могут вести себя иначе.
Использование IDT запускается тремя типами событий: аппаратными прерываниями, программными прерываниями и исключениями процессора, которые вместе называются прерываниями. IDT состоит из 256 векторов прерываний, первые 32 из которых (0–31 или 0x00–0x1F) зарезервированы для исключений процессора.
В процессоре 8086 таблица прерываний называется IVT (таблица векторов прерываний). IVT всегда находится в одном и том же месте в памяти, в диапазоне от 0x0000
до 0x03ff
, и состоит из 256 четырехбайтовых указателей реального режима дальних указателей (256 × 4 = 1024 байта памяти).
Указатель реального режима определяется как 16-битный сегмент и 16-битное смещение в этом сегменте. Сегмент внутренне расширяется процессором до 20 бит, сдвигая его на 4 бита влево, таким образом ограничивая обработчики прерываний реального режима первым 1 мегабайтом памяти. Первые 32 вектора зарезервированы для внутренних исключений процессора, а аппаратные прерывания могут быть отображены на любой из векторов с помощью программируемого контроллера прерываний.
На 80286 и более поздних версиях размер и расположение IVT могут быть изменены таким же образом, как это сделано с IDT в защищенном режиме (т. Е., с помощью инструкции LIDT), хотя это не меняет ее формат. 80286 также представил область верхней памяти , которая увеличивает ограничение адреса в реальном режиме на 65 520 байт.
Обычно используемым прерыванием реального режима x86 является INT 10
, код Video BIOS для обработки примитивных функций рисования экрана, таких как рисование пикселей и изменение разрешения экрана.
В защищенном режиме IDT представляет собой массив дескрипторов, последовательно хранящихся в памяти и индексированных вектором прерывания. Длина полностью заполненного IDT составляет 2 КБ в 32-битном защищенном режиме (256 записей по 8 байтов каждая) и 4 КБ в 64-битном защищенном режиме (256 записей по 16 байтов каждая). Нет необходимости использовать все возможные записи: достаточно заполнить IDT до самого высокого используемого вектора прерывания и соответственно установить часть длины IDT для IDTR
.
IDT защищенного режима может находиться где угодно в физической памяти. В процессоре есть специальный регистр (IDTR
) для хранения как физического базового адреса, так и длины IDT в байтах. Когда происходит прерывание, процессор умножает вектор прерывания на размер дескриптора и добавляет результат к базовому адресу IDT. Затем с помощью длины IDT проверяется, находится ли результирующий адрес памяти в таблице; если он слишком большой, создается исключение. Если все в порядке, загружается дескриптор, хранящийся в вычисленной ячейке памяти, и предпринимаются действия в соответствии с типом и содержимым дескриптора.
Дескрипторы могут быть либо шлюзами прерывания, либо шлюзами-ловушками, либо, только для 32-битного защищенного режима, шлюзами задач. Шлюзы прерывания и ловушки указывают на ячейку памяти, содержащую код для выполнения, указывая как сегмент (присутствующий в GDT или LDT ), так и смещение внутри этого сегмента. Единственное различие между этими двумя параметрами заключается в том, что шлюз прерывания отключает дальнейшую обработку процессором аппаратных прерываний, что делает его особенно подходящим для обслуживания аппаратных прерываний, в то время как шлюз прерывания оставляет аппаратные прерывания включенными и, таким образом, в основном используется для обработки программных прерываний и исключений. Наконец, шлюз задачи вызовет переключение текущего активного сегмента состояния задачи, используя аппаратный механизм переключения задач, чтобы эффективно передать использование процессора другой программе, потоку или процессу.
Векторы 0–31 зарезервированы Intel для исключений, генерируемых процессором (общая ошибка защиты, ошибка страницы и т. Д.). В настоящее время процессоры Intel используют только векторы 0–20, а процессоры AMD используют векторы 0–19 и 29–30. Однако будущие процессоры могут создать несовместимость для сломанного программного обеспечения, которое использует эти векторы для других целей.
Все INT_NUM от 0x0 до 0x1F включительно зарезервированы для исключений; INT_NUM больше 0x1F используются для обработки прерываний. (Обратите внимание, что IBM PC не всегда подчинялся этому правилу, например, используя прерывание 5, чтобы указать, что была нажата клавиша Print Screen.)
INT_NUM | Краткое описание PM |
---|---|
0x00 | Деление на ноль |
0x01 | Одношаговое прерывание (см. флаг прерывания ) |
0x02 | NMI |
0x03 | Точка останова (вызывается специальной 1-байтовой инструкцией 0xCC, используемой отладчиками) |
0x04 | Переполнение |
0x05 | Границы |
0x06 | Неверный код операции |
0x07 | Сопроцессор недоступен |
0x08 | Двойная ошибка |
0x09 | Переполнение сегмента сопроцессора (только 386 или более ранняя версия) |
0x0A | Неверный сегмент состояния задачи |
0x0B | Сегмент отсутствует |
0x0C | Ошибка стека |
0x0D | Общая ошибка защиты |
0x0E | Страница ошибка |
0x0F | зарезервировано |
0x10 | Math Fault |
0x11 | Alignment Check |
0x12 | Machine Check |
0x13 | SIMD Исключение с плавающей точкой |
0x14 | За исключением виртуализации ion |
0x15 | Исключение защиты управления |
Некоторые программы Windows перехватывают вызовы IDT. Для этого нужно написать драйвер режима ядра , который перехватывает вызовы IDT и добавляет свою собственную обработку. Это никогда официально не поддерживалось Microsoft, но не было программно предотвращено в его операционных системах до 64-битных версий Windows, где драйвер, который пытается использовать ядро Mode вызовет проверку ошибок.