6

通常,x86-64 架构提供与 x86 的兼容性。32 位 Windows(或其他操作系统)可以在 x86-64 处理器上运行。(如果我错了,请纠正我)。

我想知道 32 位 Windows 是否有可能(在 C++ 中)知道底层处理器是否为 64 位。例如,如果 Windows 7 32 位在 Core i5 上运行,我们应该能够知道处理器是 64 位的(尽管 Windows 7 32 位正在运行)。

您可能会质疑即使处理器是 64 位并且操作系统是 32 位,64 位进程也无法运行的要求(如果我错了,请纠正我)。但是程序的目的是了解处理器,而不是操作系统。 这个问题可能看起来与此类似,但它没有给出任何 C++ 程序的提示。

4

2 回答 2

6

这不是 C++ 解决方案,但它似乎在 C# 中工作。
但是应该很容易转换为 C++,因为关键点在 API 结构SYSTEM_INFO和 API GetNativeSystemInfo()

首先是对获取信息的 API 的引用

[DllImport("kernel32.dll")]
public static extern void GetNativeSystemInfo
              ([MarshalAs(UnmanagedType.Struct)] ref SYSTEM_INFO lpSystemInfo);

然后是结构 SYSTEM_INFO 和 _PROCESSOR_INFO_UNION

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_INFO
{
    internal _PROCESSOR_INFO_UNION uProcessorInfo;
    public uint dwPageSize;
    public IntPtr lpMinimumApplicationAddress;
    public IntPtr lpMaximumApplicationAddress;
    public IntPtr dwActiveProcessorMask;
    public uint dwNumberOfProcessors;
    public uint dwProcessorType;
    public uint dwAllocationGranularity;
    public ushort dwProcessorLevel;
    public ushort dwProcessorRevision;
}

[StructLayout(LayoutKind.Explicit)]
public struct _PROCESSOR_INFO_UNION
{
    [FieldOffset(0)]
    internal uint dwOemId;
    [FieldOffset(0)]
    internal ushort wProcessorArchitecture;
    [FieldOffset(2)]
    internal ushort wReserved;
}

现在是一个枚举来简化调用本机 API 的代码和方法

public enum ProcessorArchitecture
{
    Unknown = 0,
    Bit32 = 1,
    Bit64 = 2,
    Itanium64 = 3
}

static public ProcessorArchitecture ProcessorBits
{
    get
    {
        ProcessorArchitecture pbits = ProcessorArchitecture.Unknown;
        SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
        GetNativeSystemInfo(ref l_System_Info);

        switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
        {
            case 9: // PROCESSOR_ARCHITECTURE_AMD64
                pbits = ProcessorArchitecture.Bit64;
                break;
            case 6: // PROCESSOR_ARCHITECTURE_IA64
                pbits = ProcessorArchitecture.Itanium64;
                break;
            case 0: // PROCESSOR_ARCHITECTURE_INTEL
                pbits = ProcessorArchitecture.Bit32;
                break;
            default: // PROCESSOR_ARCHITECTURE_UNKNOWN
                pbits = ProcessorArchitecture.Unknown;
                break;
        }
        return pbits;
    }
}
于 2012-08-31T09:48:18.363 回答
5

好吧,据我所知,您只能通过查看 CPU 信息本身来获得此信息。我认为检查 CPU 是否支持长模式应该足够了(对于 x86 和 amd64)。

为此,您可以使用cpuidx86 上的指令。根据您帖子的 Windows 特性,我猜您正在使用 Microsoft C++ 编译器。为此,有一个__cpuid内在的. 可悲的是,微软页面上的描述以PBEflag 结尾,而lm我的 cpuinfo 中的 flag 在三个 flag 之后。

查看AMD 处理器的 CPUID 修改,您可以得到LMInfoType = 0x80000001结果位于最后返回的整数的第 29 位。在Intel 处理器的 CPUID 修改中,相同的位指定EM64T了等效于 AFAIK 的标志。

在这两种情况下,您都应该InfoType = 0x80000000首先获得最大的有意义的InfoType价值。如果它小于0x80000001,那么您不应该进行上述检查,而是假设不支持长模式。

于 2012-08-31T09:46:17.123 回答