6

Normally, x86-64 architecture offers compatibility with x86. A 32-bit Windows (or other OS) can run on an x86-64 processor. (Correct me if I am wrong).

I would like to know if it is possible (in C++) for a 32-bit Windows to know that if underlying processor is 64-bit. For example, if Windows 7 32-bit running on Core i5, we should be able to know that processor is 64-bit (although Windows 7 32 bit is running).

You may question the requirement that even if processor is 64 bit and OS is 32 bit, 64 bit processes cannot run (Correct me if I am wrong). But the aim of the program to know the processor, not OS. This question may appear similar to this, but it does not give any hint of C++ program.

Community
  • 1
  • 1
doptimusprime
  • 9,115
  • 6
  • 52
  • 90

2 Answers2

7

This is not a C++ solution, but it seems to work in C#.
However should be easily converted to C++ because the key point is in the API structure SYSTEM_INFO and the API GetNativeSystemInfo()

First a reference to the API that gets infos

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

then the structure SYSTEM_INFO and the _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;
}

Now an enum to simplify the code and the method that calls the native 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;
    }
}
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Thanks Steve for the solution. It has solved my problem for WOW64 processes.But I also want to detect if the processor is 64 bit when OS is 32-bit. MSDN documentation says "Retrieves information about the current system to an application running under WOW64. If the function is called from a 64-bit application, it is equivalent to the GetSystemInfo function." I was using GetSystemInfo for this. – doptimusprime Aug 31 '12 at 10:58
  • I don't get it. Changing `GetNativeSystemInfo` in `GetSystemInfo` doesn't work in your case? – Steve Aug 31 '12 at 11:03
  • 1
    I think this is the difference between the `GetSystemInfo` and `GetNativeSystemInfo`. It should be working according to: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724340%28v=vs.85%29.aspx#2 – Rolice Aug 31 '12 at 11:04
  • Steve: I tested my program on Intel Core i5 machine with Windows 7 32 bit version. I got the same processor type by both `GetNativeSystemInfo` and `GetSystemInfo`. I would like to say that by program can I detect in Windows 7 32 bit that Intel Core i5 is a 64 bit processor? – doptimusprime Aug 31 '12 at 11:27
  • @Rolice Thank you for the link. This example is for 64 bit Windows. I am using 32 bit Windows over a 64-bit capable process. I think it works same way because OS is 32-bit. – doptimusprime Aug 31 '12 at 11:30
  • Can't test now. I have a Core I5 with 64bit win7. The method returns the correct processor (64bit). – Steve Aug 31 '12 at 11:34
  • Tried also on a Pentium 3 with a 32bit os (Win2003 server) - It detects the CPU bitness correctly – Steve Aug 31 '12 at 11:40
  • I should mention that I have compiled the test application as x86 – Steve Aug 31 '12 at 11:42
  • @dbasic, yes, I suppose that the `GetNativeSystemInfo` might return the processor capabilities, independently from OS architecture (32 or 64 bit), isn't it? The API should return Processor Capabilities? The topic is interesting to me also. :) – Rolice Aug 31 '12 at 13:40
6

Well, as far as I am aware, you can only get this through looking at the CPU information itself. I think it should be enough (for x86 & amd64) to check whether the CPU supports long mode.

For that, you could use the cpuid instruction on x86. By Windows-ness of your post, I'll take a guess you're using the Microsoft C++ compiler. For that, there's a __cpuid intrinsic. Sadly, the description on Microsoft's page ends at PBE flag, while lm flag in my cpuinfo goes three flags later.

Looking at CPUID Modifications for AMD Processors, you can get LM with InfoType = 0x80000001, with the result being at bit 29 of the last returned integer. In CPUID Modifications for Intel Processors the same bit specifies EM64T flag which is equivalent AFAIK.

In both cases, you should be doing InfoType = 0x80000000 first to get maximum meaningful InfoType value. If it's less than 0x80000001, then you should not do the above check and instead assume long mode is not supported.

Michał Górny
  • 18,713
  • 5
  • 53
  • 76
  • Thanks Michal for the solution. What does cache line size signifies? Can it also be used to identify 64 bit/32 bit processor? – doptimusprime Aug 31 '12 at 11:22
  • @dbasic: I don't think that's strictly relevant, and you really shouldn't depend on that. By the way, if you decide to use that and write some code for it, feel free to edit my answer and add it there so others could benefit. I don't have MSVC around to hack it myself. – Michał Górny Aug 31 '12 at 11:36