检查给定的程序集文件是否应该 运行 在给定的处理器上

Checking whether a given assembly file should run on a given processor

我想汇编一个 x86 文件,同时确保代码 运行 在给定的处理器上运行,而无需在处理器模拟器上进行测试。

是否有 tool/technique 允许我根据支持它的最旧所需处理器进行某种 x86 指令分类,或者至少在使用不兼容指令时警告我?

简而言之,我正在寻找 this Wikipedia table of x86 instruction listings 的自动化版本,以帮助我检查给定代码是否应与给定处理器兼容。

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 Assemble只有8086指令集
  • 186 Assemble 指令最多80186指令集
  • 286 Assemble 最多286个指令集的指令
  • 386 Assemble 指令最多386指令集
  • 486486指令集
  • 586奔腾指令集
  • PENTIUM 同 586
  • 686 P6指令集
  • PPRO 同686
  • P2 与 686
  • 相同
  • P3 奔腾 III (Katmai) 指令集
  • KATMAI同P3
  • P4 奔腾 4 (Willamette) 指令集
  • WILLAMETTE同P4
  • PRESCOTT Prescott 指令集
  • X64x86-64(x64/AMD64/Intel64)指令集
  • IA64 IA64 CPU(在x86模式下)指令集

后跟您的代码。然后调用 NASM 到 assemble 该文件,并观察 NASM 的退出状态和错误消息。如果您不使用 NASM.

,TASM/MASM 也有类似的指令

一个例子:

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

我 运行 在旧的 Athlon XP 上启动 32 位 Ubuntu GNU/Linux 时遇到了这个问题。一些程序死于 SIGILL(非法指令)。

我假设 Ubuntu 使用 -mfpmath=sse 编译甚至 32 位代码,并且崩溃的程序使用双精度浮点(即 SSE2)。 Athlon XP 不支持 SSE2。 AMD64 k8 CPU 是第一个支持它的 AMD CPU。

在反汇编中寻找movsd / addsd / comisd。 (s = 标量,d = 双精度。也可以是 movapd / movupd / addpd / 等(p = 压缩)。grep(或搜索 less) 对于 [sp]d .*%xmm,这可能会找到任何 SSE2 指令。打包的 32 位 int 指令也倾向于以 d 结尾(例如 pshufd),但它们也是 SSE2 或更高版本。

正如@nrz 正确指出的那样,并非程序中的每条指令都会 运行。此外,.text 段的某些部分实际上可能是数据,而不是代码。不过,请在反汇编输出中查找 CPUID 指令,以查看程序是否检查了它 运行 正在使用哪种 CPU。

我很喜欢@Michael 反汇编成临时文件的想法,添加 CPU 限制,然后在 assemble.

时检查错误