2015-07-20 2 views
2

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

Есть ли инструмент/техника, которая позволила бы мне сделать какую-либо классификацию команд x86 в соответствии с самым старым требуемым процессором, который ее поддерживает, или, по крайней мере, предупредить меня, если используются несовместимые инструкции?

Короче говоря, я ищу автоматическую версию this Wikipedia table of x86 instruction listings, чтобы помочь мне проверить, должен ли данный код быть совместимым с данным процессором.

+6

Инструкции, представленные в сборке/двоичном коде, не обязательно выполняются. Большинство программ, которые используют современные инструкции, также содержат обратную совместимость версий оптимизированных функций и выполняются в зависимости от процессора, обнаруженного во время выполнения. –

+0

В этом случае консервативная оценка с учетом * каждой инструкции в файле * была бы достаточно для меня. У меня есть код, запущенный на старых процессорах, извергающих ошибки, такие как «iilegal opcode/инструкция» и сброс, и я хотел бы иметь возможность понять, почему без необходимости вручную проверять каждую инструкцию по таблице или запускать ее через серию эмуляторов процессора, чтобы увидеть, какой из них терпит неудачу. – anol

+2

Окончательная классификация инструкций двоичного кода (исполняемый или объектный код) невозможна, поскольку это означает решение [** проблемы с остановкой **] (https://en.wikipedia.org/wiki/Halting_problem), которая доказана * * неразрешимой **. Невозможно окончательно отличить код и данные по той же причине (проблема с остановкой). Конечно, существуют эвристики и более простые методы, которые могут работать или нет, например метод линейной развертки, используемый некоторыми дизассемблерами. – nrz

ответ

7

In short, I'm looking for an automated version of this Wikipedia table of x86 instruction listings, to help me check if a given code should be compatible with a given processor.

Вы могли испускать временный файл сборки со следующей директивой:

[CPU level] 

Где level является одним из:

  • 8086 Собирают только 8086 набор инструкций
  • 186 Соберите инструкции до 80186 набора команд
  • 286 Соберите инструкции до 286 набора команд
  • 386 Соберите инструкции до 386 набора команд
  • 486 486 набора команд
  • 586 Набор инструкций Pentium
  • PENTIUM То же, что 586
  • 686 инструкция P6 установить
  • PPRO То же, что 686
  • P2 То же 686
  • P3 Pentium III (Katmai) инструкция устанавливает
  • KATMAI То же, что Р3
  • P4 Pentium 4 (Willamette) набор инструкций
  • WILLAMETTE То же, что Р4
  • инструкция PRESCOTT Прескотт установить
  • X64 x86-64 (x64/AMD64/Intel 64)
  • IA64 IA64 CPU (в режиме x86) набор инструкций

а затем код. Затем вызовите NASM, чтобы собрать этот файл, и наблюдать за состоянием выхода и сообщением об ошибке с NASM. Существуют аналогичные директивы для TASM/MASM, если вы не используете NASM.


Пример:

test8086.ASM

[cpu 8086] 
cmovne eax,ebx ; Not a part of the 8086 instruction set 


C:\nasm>nasm -f bin -o test8086.com test8086.asm 
test8086.asm:2: error: no instruction for this cpu level 

C:\nasm>echo %errorlevel% 
1 
+0

Отлично. Я смог сделать это на GNU 'as', добавив инструкцию' rdtsc', а затем попытался собрать ее с помощью файла 'as -32 -march = i386.s', и он правильно отклонил его с помощью 'Error: 'rdtsc' не поддерживается на 'i386''. – anol

+0

Я думаю, что ясность тоже может это сделать. x264 использует эту функцию, чтобы убедиться, что функция, объявленная как SSSE3, фактически не использует никаких инструкций из SSE4. –

0

Я столкнулся с этой проблемой при загрузке 32-битной Ubuntu GNU/Linux на старом Athlon XP. Несколько программ умерли с SIGILL (незаконная инструкция).

Я предполагаю, что Ubuntu компилирует даже 32-битный код с -mfpmath=sse, а в программах, которые были разбиты, использовались с плавающей запятой с двойной точностью (т. Е. SSE2). Athlon XP не поддерживает SSE2. Процессоры AMD64 k8 были первыми процессорами AMD для его поддержки.

Ищите movsd/addsd/comisd при разборке. (s = скаляр, d = двойной). Также может быть movapd/movupd/addpd/и т. д. (p = упакованный). grep (или поиск в less) для [sp]d .*%xmm, и, вероятно, должны найти инструкции SSE2. также имеют тенденцию заканчиваться на d (например, pshufd), но это SSE2 или выше.

Как @nrz правильно указывает, не каждая команда в программе будет работать. Кроме того, некоторые части сегмента .text могут фактически быть данными, а не кодом. Тем не менее, ищите инструкцию CPUID на выходе разборки, чтобы узнать, проверяет ли программа, какой процессор он работает.

Мне нравится идея Михаэля о разборке временного файла, добавление ограничения ЦП, а затем проверка ошибок при сборке.