在运行时以编程方式检测 CPU 架构
Programmatically detect CPU architecture at runtime
是否可以在 x86/x86-64 CPU 中检查 CPU 架构(是 64 位还是 32 位)而不从 OS 或某些 API,通过底层代码(C/C++ 或汇编)?
可以检查指针的大小,就像讨论的那样 here,但是,据我了解,这种方式让你知道 OS 架构是为编译的,因为 64 位CPU 运行 32 位 OS 会报告错误的结果。
也许某些 cpuid
指令或类似指令可以解决问题,但我找不到完全满足这些要求的任何指令。如果您认为这是不可能的,我会很感激有充分的理由来证明这一点(这可能是一个较少的 objective 答案)。如果你想知道,这是一个 CPU 检测软件。
编辑:
在 Determine 32/64 bit architecture in assembly, OP does not get some specific answer that explain how to do it, just that you should use cpuid, and links to How do you detect the CPU architecture type during run-time with GCC and inline asm? 中,这对我来说是一个很好的答案,但它不如我标记为已接受的答案那么完整,因为 Remy Lebeau 给出了详细的解释并告诉必须查询哪个特定的 cpuid 位,而不是只是写一些代码,我发现它更适合我的问题,因为它在更高级别的范围内进行了解释(我从未提到 gcc,第二个 post 确实)
可以在 32 位或 64 位模式下为 运行 编写 x86 代码。如果您运行正在使用这样的代码,您可以使用以下方法检查您所处的模式:
get_mode:
mov eax, 1
dec eax
test eax, eax
ret
在 64 位模式下,dec eax
成为测试指令的 REX.W 前缀。因此,此代码 returns 在 32 位模式下 运行 时为 0,在 64 位模式下 运行 时 returns 1。它还会相应地设置 Z,因此它可以像这样从另一个汇编语言函数中使用:
call get_mode
jnz mode64
如果为 64 位编译可执行文件,CPU 必须仅为 64 位。
如果为 32 位编译可执行文件,CPU 可能 是 32 位或 64 位(如果 64 位 CPU 能够 运行 32位代码),所以你必须查询 CPU 来区分。最好尽可能从 OS 获取,但 CPU 可能 有自己的信息查询。
例如,在 x86 或 x86-64 CPU 上,有一个 CPUID
指令可用:
On Intel CPUs, CPUID
's "Processor Info and Feature Bits" 查询包含一个 ia64
功能标志(IA64 处理器模拟 x86)。
On AMD CPUs, CPUID
's "Extended Processor Info and Feature Bits" query includes a long mode
特征标志。
CPUID
有一个 "Get vendor ID" 查询来确定 CPU 制造商。
是否可以在 x86/x86-64 CPU 中检查 CPU 架构(是 64 位还是 32 位)而不从 OS 或某些 API,通过底层代码(C/C++ 或汇编)?
可以检查指针的大小,就像讨论的那样 here,但是,据我了解,这种方式让你知道 OS 架构是为编译的,因为 64 位CPU 运行 32 位 OS 会报告错误的结果。
也许某些 cpuid
指令或类似指令可以解决问题,但我找不到完全满足这些要求的任何指令。如果您认为这是不可能的,我会很感激有充分的理由来证明这一点(这可能是一个较少的 objective 答案)。如果你想知道,这是一个 CPU 检测软件。
编辑: 在 Determine 32/64 bit architecture in assembly, OP does not get some specific answer that explain how to do it, just that you should use cpuid, and links to How do you detect the CPU architecture type during run-time with GCC and inline asm? 中,这对我来说是一个很好的答案,但它不如我标记为已接受的答案那么完整,因为 Remy Lebeau 给出了详细的解释并告诉必须查询哪个特定的 cpuid 位,而不是只是写一些代码,我发现它更适合我的问题,因为它在更高级别的范围内进行了解释(我从未提到 gcc,第二个 post 确实)
可以在 32 位或 64 位模式下为 运行 编写 x86 代码。如果您运行正在使用这样的代码,您可以使用以下方法检查您所处的模式:
get_mode:
mov eax, 1
dec eax
test eax, eax
ret
在 64 位模式下,dec eax
成为测试指令的 REX.W 前缀。因此,此代码 returns 在 32 位模式下 运行 时为 0,在 64 位模式下 运行 时 returns 1。它还会相应地设置 Z,因此它可以像这样从另一个汇编语言函数中使用:
call get_mode
jnz mode64
如果为 64 位编译可执行文件,CPU 必须仅为 64 位。
如果为 32 位编译可执行文件,CPU 可能 是 32 位或 64 位(如果 64 位 CPU 能够 运行 32位代码),所以你必须查询 CPU 来区分。最好尽可能从 OS 获取,但 CPU 可能 有自己的信息查询。
例如,在 x86 或 x86-64 CPU 上,有一个 CPUID
指令可用:
On Intel CPUs,
CPUID
's "Processor Info and Feature Bits" 查询包含一个ia64
功能标志(IA64 处理器模拟 x86)。On AMD CPUs,
CPUID
's "Extended Processor Info and Feature Bits" query includes along mode
特征标志。
CPUID
有一个 "Get vendor ID" 查询来确定 CPU 制造商。