Win32 EXCEPTION_INT_OVERFLOW против EXCEPTION_INT_DIVIDE_BY_ZERO - PullRequest
10 голосов
/ 15 февраля 2011

У меня есть вопрос об исключениях EXCEPTION_INT_OVERFLOW и EXCEPTION_INT_DIVIDE_BY_ZERO.

Windows будет перехватывать ошибки #DE, сгенерированные инструкцией IDIV, и в результате генерирует исключение SEH с одним из этих 2 кодов.

У меня вопрос: как он различает два условия?Информация о idiv в руководстве Intel указывает на то, что он будет генерировать #DE как в «делении на ноль», так и в «случаях недостаточного заполнения».

Я быстро взглянул на раздел об ошибке #DE в Volume3 руководства Intel, и самое лучшее, что я могу собрать, это то, что ОС должна декодировать инструкцию DIV, загружать аргумент делителя и затем сравнивать его с нулем.

Хотя это кажется мне немного сумасшедшим.Почему разработчики чипов не используют какой-либо флаг, чтобы различать 2 причины ошибки?Мне кажется, что я что-то упускаю.

Кто-нибудь знает наверняка, как ОС различает две разные причины сбоя?

Ответы [ 2 ]

6 голосов
/ 15 февраля 2011

Ваши предположения кажутся правильными. Единственная информация, доступная на #DE, - это CS и EIP, которые дают инструкцию. Поскольку два кода состояния различны, ОС должна декодировать инструкцию, чтобы определить, какие именно.

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

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


Редактировать: Поиграв с kd, я могу, по крайней мере, сказать, что в конкретной версии Windows XP (32-разрядной) у меня был доступ (и процессор, на котором он работал) к nt!Ki386CheckDivideByZeroTrap По-видимому, обработчик прерываний декодирует значение ModRM инструкции, чтобы определить, следует ли возвращать STATUS_INTEGER_DIVIDE_BY_ZERO или STATUS_INTEGER_OVERFLOW.

(Очевидно, что это оригинальное исследование, нигде никому не гарантированное, а также оно соответствует выводам, которые могут быть сделаны на основании руководств Intel.)

1 голос
/ 09 января 2015

Ответ Zooba суммирует, что Windows анализирует инструкцию, чтобы выяснить, что поднять.

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

На 64-битной Windows 7 с 64-битными инструкциями DIV я наблюдал следующее:

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

У меня ушел день, чтобы это выяснить ... Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...