检测处理器在32位操作系统下是否为64位

Detect if the processor is 64-bit under 32 bit OS

本文关键字:是否 64位 操作系统 处理器 32位 检测      更新时间:2023-10-16

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

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

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

这不是一个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;
}

现在是一个enum,用于简化调用本地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;
    }
}

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

为此,您可以在x86上使用cpuid指令。根据你文章的Windows特性,我猜你使用的是Microsoft C++编译器。为此,有一个内在的__cpuid。遗憾的是,微软页面上的描述以PBE标志结束,而我的cpuinfo中的lm标志在三个标志之后结束。

查看AMD处理器的CPUID修改,您可以使用InfoType = 0x80000001获得LM,结果位于最后返回的整数的第29位。在"针对英特尔处理器的CPUID修改"中,相同的位指定等效于AFAIK的EM64T标志。

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