检查给定的程序集文件是否应该 运行 在给定的处理器上
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指令集
486
486指令集
586
奔腾指令集
PENTIUM
同 586
686
P6指令集
PPRO
同686
P2
与 686 相同
P3
奔腾 III (Katmai) 指令集
KATMAI
同P3
P4
奔腾 4 (Willamette) 指令集
WILLAMETTE
同P4
PRESCOTT
Prescott 指令集
X64
x86-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.
时检查错误
我想汇编一个 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指令集486
486指令集586
奔腾指令集PENTIUM
同 586686
P6指令集PPRO
同686P2
与 686 相同
P3
奔腾 III (Katmai) 指令集KATMAI
同P3P4
奔腾 4 (Willamette) 指令集WILLAMETTE
同P4PRESCOTT
Prescott 指令集X64
x86-64(x64/AMD64/Intel64)指令集IA64
IA64 CPU(在x86模式下)指令集
后跟您的代码。然后调用 NASM
到 assemble 该文件,并观察 NASM
的退出状态和错误消息。如果您不使用 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
我 运行 在旧的 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.
时检查错误