Win32 EXCEPTION_INT_OVERFLOW vs EXCEPTION_INT_DIVIDE_BY_ZERO

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

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

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

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

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

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

Ответ 1

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

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

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


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

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

Ответ 2

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

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

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

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

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