Возникла следующая проблема. Я написал прогу, которая переводит проц в защищенный режим и обрабатывает прерывания. Все это до тех пор, пока я не нажму esc. Проверка идет просто, в цикле проверяю содержимое порта 60h. Проблема такая. После перепрограммирования контроллера прерываний я размаскировал только прерывание от клавы. Но, активируется почему-то при нажатии клавиш обработчик для irq7. Описание IDT проверил несколько раз вроде все нормально. Что это может быть.
Я сравнил Ваш пример со своим - вроде бы немного по-разному инициализируется контроллер (reprogram_8259). Возможно, причина еще в чем-то...
Вроде бы разобрался с твоим примером... Я бы перечислил ошибки, но их слишком много Основные: 1) Неверно инициализируется контроллер - из-за этого прерывания не возникали, я исправил это; 2) Неверно определены ловушки (их должно быть 20h, потом уже идут прерывания), неверно определен атрибут в описателе прерывания (нужно 8Eh); 3) Команда iret в обработчиках прерывания вызывает исключение 0Dh, нужно дописать db 66h. Ну и так далее... Смотри исправленный пример (правда, он теперь виснет при выходе в дос, но прерывания точно работают). Также рекомендую посмотреть как у меня идет работа в обработчике прерывания от клавиатуры с портами. ++ Добавлены нормальные обработчики исключений - они выводят номер исключения и кусок стека (там адрес исключения и т.п.)
Большое спасибо. Вчера разбирался с тем, что вы доделали. Хочу немного прокомментировать те ошибки, которые вы отметили. 1. Про неверную инициализацию контроллера прерываний. Я заменил в вашем примере процедуру перепрограммирования ПКП на свою. Все работает! 2. Атрибут 8Еh в описателе прерываний указывает на то, что шлюз-32 битный. Т.к. у меня все сегменты определены с атрибутом use16 и в GDT все дескрипторы описывают сегменты как 16 битные, то и в описании шлюза я использовал 86h. Отсюда следует ... 3. db 66h перед iret не нужно. Моя проблема была в другом. У меня работали прерывания, но как-то странно. У вас с ними все нормально. Сейчас ищу разницу между вашим примером и своим. Еще раз спасибо.
Да не за что Я не особенно разбираюсь в тонкостях PM, скорее я делал "чтобы работало, ориентируясь на точно работающую программу". Сначала я принудительно вызвал исключение деления на 0 - номер ноль. Оно успешно вызвалось, так я убедился, что таблица прерываний более-менее правильно загружена. Прерывания по-прежнему не работали. Тут я заметил, что исключений не 20h, а другое число. Обработчки прерывний должны идти следом. Я исправил это, а также атрибут в дескрипторе прерывания, меня также смутило что у ловушек и прерываний он одинаковый, заменил инициализацию контроллера. Тут же возникло исключение. Я более подробно вывел информацию по исключению, адрес краша. Так я понял, что исключение 0Dh вызывает команда iret в обработчике прерываний, я исправил ее на iretd и все заработало, но не работали прерывания от клавиатуры. Затем я убрал цикл опроса порта клавиатуры 60h на просто проверку числа прерываний от таймера: lpwait: cmp word ptr ds:Int08Counter,0FFh jnz lpwait assume ds:gdt_seg После этого прерывания от клавиатуры появились. Единственное, что после выхода в DOS все виснет. В моем примере (первом) такого нет, но я не доделал все окончательно...
Ustus Не знаю, я все, что после перехода в RM обратно - не проверял (тот код, что я корректировал). Знаю только, что виснуть начало как заработали прерывания от клавиатуры (от таймера когда только были - все работало и потом), и еще - в моем примере нет такой проблемы.