Что происходит, когда Windows встречает неизвестную инструкцию в двоичном файле?

У нас есть двоичный файл, скомпилированный с оптимизацией SSE3, которая в конечном итоге использует инструкцию LDDQU. Теперь, когда этот код выполняется в системе Windows (одноядерная, XP2), которая имеет только поддержку SSE1,2 (как видно из инструмента CPU-Z), происходит сбой приложения.

(924.4f0): Неверная последовательность блокировки — код c000001e (первый шанс) ... 001700a10 f20ff00430 lddqu xmm0,xmmword ptr [eax+esi] ds:0023:1e08d200=270a57364a4a77896db676459d8c40a9 ...

Может ли кто-нибудь просветить меня, что означает этот сбой и возможные исправления?


person Manoj Awasthi    schedule 28.09.2010    source источник


Ответы (3)


Приложение скомпилировано с поддержкой SSE3 и аварийно завершает работу при запуске на ЦП, не поддерживающем SSE3. Гы, как странно! Опции компилятора для выбора набора инструкций должны быть там только потому, что какому-то программисту в Microsoft однажды стало чертовски скучно.

У вас есть несколько вариантов:

  • сделать одну версию приложения, используя только набор инструкций SSE2
  • делать разные версии приложения, скомпилированные с разными наборами инструкций
  • используйте структурированную обработку исключений (SEH) для реализации эмуляции неподдерживаемых инструкций в пользовательском режиме.

Последний подход требует немного больше времени, чем первые два, имеет некоторые проблемы с производительностью, но эти недостатки намного меньше, чем преимущества, которые он дает. Если вы выберете третье решение, вы также сможете изобретать свои собственные коды операций! Идеальный способ запутать поток управления программой, что опять-таки очень полезно для предотвращения реинжиниринга вашей программы и, таким образом, защиты вашей ИП.

person zvrba    schedule 28.09.2010
comment
Есть по крайней мере один дополнительный вариант, который активно реализуется компилятором Intel: * создать единую версию приложения, используя пути кода SSE2 и SSE3. Во время выполнения ветвление в зависимости от процессора. - person MSalters; 28.09.2010

Это аппаратное обеспечение, которое сталкивается с инструкцией, которую оно не знает. Точно так же, как вы не можете позволить чипу Motorola выполнять код x86, этот процессор не распознает инструкцию LDDQU.

ЦП вызовет прерывание, которое обрабатывается ОС и преобразуется в полученное вами сообщение об ошибке.

Что ты можешь сделать? Вы также можете создать свой двоичный файл только для платформы «нижнего уровня». Вероятно, целевой "x86" подойдет. Затем компилятор выдаст код, совместимый с x86. Вы можете выпустить свое программное обеспечение в двух версиях: «оптимизированной» и «совместимой».

person xtofl    schedule 28.09.2010

Он должен вызвать исключение, как правило, EXCEPTION_ILLEGAL_INSTRUCTION из msdn:

EXCEPTION_ILLEGAL_INSTRUCTION Поток попытался выполнить недопустимую инструкцию.

однако в вашем случае ЦП не смог должным образом взаимодействовать с потоком выполнения и разбил его на более мелкие части, что привело к неопределенному поведению (в этом случае к некоторой инструкции был добавлен префикс LOCK из остаточного байта из инструкции SSE3, но он не поддерживает префикс LOCK и генерирует исключение). на самом деле ничего не нужно делать, кроме как сделать версию SSE2 или протестировать ошибки SSE и разбить код на основе того, что поддерживается)

person Necrolis    schedule 28.09.2010