【问题标题】:Detect whether the system can run amd64 executables检测系统是否可以运行amd64可执行文件
【发布时间】:2016-06-14 11:34:53
【问题描述】:

我已将我的应用程序编译为使用 x86 指令集,但我需要以编程方式了解运行可执行文件的机器是否支持 amd64 指令集。有没有一种简单的方法来解决这个问题(可能使用CPUID)?

应用程序需要能够在多个操作系统上运行,因此首选非基于操作系统的方法。

【问题讨论】:

  • 这只是告诉我代码是为什么架构编译的,而不是代码的运行时模式
  • @doron:如果它是为 x86 编译的,它将不会使用 64 位指令,而当为 x64 编译时,它不能在 x86 上运行。您的问题看起来像是 XY 问题,您的目标是什么?
  • @Olaf 一个明显的例子是 32 位启动器,然后根据架构启动正确的可执行文件(32 位或 64 位)。
  • 这实际上是相当没用的。您实际上并不关心处理器的本机功能是什么。重要的是主机操作系统支持什么。如果我有一个能够支持 x86-64 的 CPU,但我运行的是 32 位操作系统,那么任何应用程序都绝对不可能利用 64 位扩展。操作系统不支持它,因此处理器上未启用这些功能。所以你真的确实需要一种特定于操作系统的方法来检测这些信息。
  • @Olaf 不一定。许多支持 64 位的操作系统可以运行 32 位程序。完全可以将 32 位和 64 位可执行文件与单独的 32 位启动器一起分发,该启动器选择适当的可执行文件 - 如果操作系统/体系结构支持 64 位,则为 64 位,否则为 32 位。

标签: c++ c x86 x86-64


【解决方案1】:

您正在寻找检测Long mode 的代码。

CPUID 扩展属性字段中的一个位会通知处于实模式或受保护模式的程序处理器是否可以进入长模式,从而允许程序检测 x86-64 处理器。这类似于 Intel IA-64 处理器用来允许程序检测它们是否在 IA-32 仿真下运行的 CPUID 属性位。

有问题的标志是CPUID query for 80000001hEDX 中的第29 位。

CPUID 指令基础结构有点冗长:如果您认为CPUID 甚至可用,那么您必须在启动该确切查询之前查询它实际支持的内容。然后你需要将寄存器结果放入你的变量中。


这是一些代码,用 C/C++ 的内联汇编程序编写。如果您使用的是 gcc,抱歉:您必须自己转换为(可怕的!)gasm 语法!

// Only on Pentium4 or above
// Only available on 32-bit
bool HasLongMode() {
    __asm {
        mov   eax,0x80000001 // Ask for processor features
        cpuid                // from the CPU
        xor   eax,eax        // Zero return value
        test  edx,0x20000000 // Check relevant bit
        setnz al             // Was bit set?
    } // __asm
} // HasLongMode()

【讨论】:

  • 抱歉:我正要写!而且我需要测试它是否有效……您使用的是什么编译器(和/或汇编器)?
  • 可能会使用编译器内在函数。不过谢谢,那里应该有足够的信息让我继续前进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多