Reputation: 9115
I'd like to assembly an x86 file while ensuring that the code will run on a given processor, without having to test it on a processor emulator.
Is there a tool/technique which would allow me to do some sort of x86 instruction classification according to the oldest required processor that supports it, or at least to warn me if incompatible instructions are being used?
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.
Upvotes: 2
Views: 273
Reputation: 365971
I ran into this problem when booting 32bit Ubuntu GNU/Linux on an old Athlon XP. A few programs died with SIGILL (illegal instruction).
I assume Ubuntu compiles even 32bit code with -mfpmath=sse
, and the programs that crashed were using double-precision floating point (i.e. SSE2). Athlon XP doesn't support SSE2. AMD64 k8 CPUs were the first AMD CPUs to support it.
Look for movsd
/ addsd
/ comisd
in the disassembly. (s = scalar, d = double. There could also be movapd
/ movupd
/ addpd
/ etc. (p = packed). grep
(or search in less
) for [sp]d .*%xmm
, and that should probably find any SSE2 instructions. packed 32bit int instructions also tend to end with d (e.g. pshufd
), but those are SSE2 or higher as well.
As @nrz correctly points out, not every instruction in a program will run. Also, some parts of the .text
segment may actually be data, not code. Still, look for the CPUID
instruction in disassembly output to see if the program checks what kind of CPU it's running on.
I do like @Michael's idea of disassembling to a temp file, adding a CPU limitation, and then checking for errors when you assemble.
Upvotes: 0
Reputation: 58507
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.
You could emit a temporary assembly file with the following directive:
[CPU level]
Where level
is one of:
8086
Assemble only 8086 instruction set186
Assemble instructions up to the 80186 instruction set286
Assemble instructions up to the 286 instruction set386
Assemble instructions up to the 386 instruction set486
486 instruction set586
Pentium instruction setPENTIUM
Same as 586686
P6 instruction setPPRO
Same as 686P2
Same as 686P3
Pentium III (Katmai) instruction setsKATMAI
Same as P3P4
Pentium 4 (Willamette) instruction setWILLAMETTE
Same as P4PRESCOTT
Prescott instruction setX64
x86-64 (x64/AMD64/Intel 64) instruction setIA64
IA64 CPU (in x86 mode) instruction setfollowed by your code. Then invoke NASM
to assemble that file, and observe the exit status and error message from NASM
. There are similar directives for TASM/MASM in case you're not using NASM.
An example:
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
Upvotes: 7