5

I have compiled my application to using the x86 instruction set but I need to know programatically whether the machine the executable is running on supports the amd64 instruction set or not. Is there a simple way to find this out (possibly using CPUID)?

The application needs to be able to run on multiple OSes so non-OS based methods are preferred.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
doron
  • 27,972
  • 12
  • 65
  • 103
  • [This](http://stackoverflow.com/a/7495023/4342498) may do the trick for you. – NathanOliver Jun 14 '16 at 11:39
  • 1
    That only tells me what architecture the code was compiled for, not the runtime mode of the code – doron Jun 14 '16 at 11:54
  • 1
    @doron: If it was compiled for x86 it will not utilise 64 bit instructions and when compiled for x64 it cannot run on x86. Your question looks like an XY-problem, what is your goal? – too honest for this site Jun 14 '16 at 11:56
  • 1
    @Olaf one obvious example would be a 32-bit launcher which then launches the correct executable (either 32- or 64-bit) depending on the architecture. – davmac Jun 14 '16 at 12:06
  • If your are supplying different executables for every OS, the installer can choose which version they want. Why does your program need to make the decision? If they want to run a 64-bit program on a 32-bit system, the OS will tell them that they can't do it. You don't have to. – cup Jun 14 '16 at 12:11
  • @davmac: The launcher would be OS-specific and well know the platform it uses. No need for what OP asks for. – too honest for this site Jun 14 '16 at 12:18
  • I want to roll out a single binary for both 32bit or 64bit. – doron Jun 14 '16 at 12:51
  • @doron I'm afraid there is no simple solution. What you need is some kind of packager that allows you to package the 32bit executable and the 64 bit executable into some "container executable" and when you run the latter, it would extract the 32/64 bit executable according to the OS and run it. Anyway Windows doesn't support this kind of thing natively AFAIK. – Jabberwocky Jun 14 '16 at 12:58
  • 3
    This would actually be rather useless. You don't actually care what the processor's native capabilities are. All that matters is what the host operating system supports. If I have a CPU that's capable of x86-64, but I'm running a 32-bit operating system, then there is absolutely no way that any application is going to be able to take advantage of the 64-bit extensions. The operating system doesn't support it, and those features are therefore not enabled on the processor. So you really *do* need an OS-specific way to detect this information. – Cody Gray - on strike Jun 14 '16 at 13:35
  • 1
    @Olaf not necessarily. Many 64-bit capable OSes can run 32-bit programs. It is entirely possible to distribute a 32-bit and 64-bit executable together together with a separate 32-bit launcher which chooses the appropriate executable - 64-bit if the OS/architecture is 64-bit capable, or 32-bit otherwise. – davmac Jun 14 '16 at 14:36
  • @davmac: Do tell! But then it is a matter of the OS launcher, not the application. – too honest for this site Jun 14 '16 at 14:39
  • @Olaf I'm afraid I either misunderstand you, or you me. I'm not talking about an OS launcher, I'm talking about an executable which acts as a launcher for another executable. – davmac Jun 14 '16 at 15:06
  • @davmac: That is a bad approach. Leave such stuff to the OS. – too honest for this site Jun 14 '16 at 15:07
  • @Olaf other than Darwin (with its "fat" binaries), I know of no OS that has such a facility. – davmac Jun 14 '16 at 17:42
  • @davmac: IIRC, the OS-X/MacOS fat bins were about having code for two different CPUs. Interestingly, there was some announcement Windows 10 (or the next "update") will support such "fat binaries", too. Anyway, I did not state the data has to be in the same binary. On Linux, libraries are loaded from `lib32` or `lib64`, depending on the requirement. Note that "executables" are just some variant of libreries in modern systems (AFAIK even Windows now uses the same format for both - but not sure). – too honest for this site Jun 14 '16 at 17:54
  • [This thread](http://stackoverflow.com/a/1290768/3808573) seems to have a marked answer. – ssd Jun 14 '16 at 19:45

1 Answers1

4

You're looking for code to detect Long mode.

A bit in the CPUID extended attributes field informs programs in real or protected modes if the processor can go to long mode, which allows a program to detect an x86-64 processor. This is similar to the CPUID attributes bit that Intel IA-64 processors use to allow programs to detect if they are running under IA-32 emulation.

The flag in question is bit 29 in EDX of the CPUID query for 80000001h.

The CPUID instruction infrastructure is a little longwinded: if you presume that CPUID is even available, you then have to query what it can actually support before launching into that exact query. And then you need to get the register results into your variable.


Here is some code, written in inline assembler for C/C++. If you're using gcc, sorry: you'll have to convert to the (horrible!) gasm syntax yourself!

// 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()
John Burger
  • 3,662
  • 1
  • 13
  • 23
  • Sorry: I was getting to it! And I needed to test it worked... What compiler (and/or assembler) are you using anyway? – John Burger Jun 14 '16 at 12:06
  • Will probably use compiler intrinsics. But thanks, there should be enough info there for me to get going. – doron Jun 14 '16 at 12:54