Несколько месяцев я работал над «самодельной» операционной системой.
В настоящее время он загружается и переходит в 32-битный защищенный режим.
Я загрузил таблицу прерываний, но пока не настроил нумерацию страниц.
Теперь, когда я писал свои подпрограммы исключения, я заметил, что когда инструкция выдает исключение, выполняется подпрограмма исключения, но затем ЦПУ возвращается к инструкции, которая вызвала исключение! Это не относится к каждому исключению (например, исключение деления на ноль будет возвращаться к инструкции ПОСЛЕ инструкции по делению), но давайте рассмотрим следующее общее исключение защиты:
MOV EAX, 0x8
MOV CS, EAX
Моя процедура проста: она вызывает функцию, которая отображает красное сообщение об ошибке.
Результат: MOV CS, EAX завершается ошибкой -> Отображается мое сообщение об ошибке -> Процессор возвращается к MOV CS -> бесконечный цикл, спамит сообщение об ошибке.
Я говорил об этой проблеме с учителем по операционным системам и безопасности Unix.
Он сказал мне, что знает, что у Linux есть способ обойти это, но он не знает, какой именно.
Наивным решением было бы проанализировать инструкцию броска из подпрограммы, чтобы получить длину этой инструкции.
Это решение довольно сложное, и я чувствую себя немного неловко, добавляя вызов к относительно тяжелой функции в каждой затронутой подпрограмме исключения ...
Поэтому мне было интересно, есть ли другой способ решения проблемы. Может быть, есть «магический» регистр, который содержит бит, который может изменить это поведение?
-
Большое спасибо заранее за любые предложения / информацию.
-
РЕДАКТИРОВАТЬ : Кажется, многие люди задаются вопросом, почему я хочу пропустить проблемную инструкцию и возобновить нормальное выполнение.
У меня есть две причины для этого:
Прежде всего, убийство процесса было бы возможным решением, но не чистым. Это не так, как это делается в Linux, например, где (AFAIK) ядро посылает сигнал (я думаю, SIGSEGV), но не сразу прерывает выполнение. Это имеет смысл, поскольку приложение может блокировать или игнорировать сигнал и возобновить собственное выполнение. Это очень элегантный способ сообщить приложению, что он что-то не так сделал IMO.
Другая причина: что, если само ядро выполняет недопустимую операцию? Может быть из-за ошибки, но также из-за расширения ядра. Как я уже сказал в комментарии: что мне делать в этом случае? Должен ли я просто убить ядро и показать хороший синий экран со смайликом?
Вот почему я хотел бы иметь возможность перепрыгнуть через инструкцию. «Угадывать» размер инструкции, очевидно, не вариант, и синтаксический анализ инструкции кажется довольно сложным (не то чтобы я возражал против реализации такой процедуры, но я должен быть уверен, что лучшего способа нет).