1

I'm using code from this forum topic in order to obtain the CPU's family information:

#include <stdio.h>

struct cpuid_type {
    unsigned int eax;
    unsigned int ebx;
    unsigned int ecx;
    unsigned int edx;
};
typedef struct cpuid_type cpuid_t;

cpuid_t cpuid(unsigned int number) 
{
    cpuid_t result; 

    __asm("movl %4, %%eax; cpuid; movl %%eax, %0; movl %%ebx, %1; movl %%ecx, %2; movl %%edx, %3;"
        : "=m" (result.eax),
          "=m" (result.ebx),
          "=m" (result.ecx),
          "=m" (result.edx)               /* output */
        : "r"  (number)                   /* input */
        : "eax", "ebx", "ecx", "edx"      /* no changed registers except output registers */
        );

    return result;
}    

int main (int argc, const char * argv[]) 
{
    cpuid_t cpuid_registers;
    unsigned int cpu_family, cpu_model, cpu_stepping;

    cpuid_registers = cpuid(1);

    cpu_family   = 0xf & (cpuid_registers.eax>>8);
    cpu_model    = 0xf & (cpuid_registers.eax>>4);
    cpu_stepping = 0xf & cpuid_registers.eax;

    printf("CPUID (1): CPU is a %u86, Model %u, Stepping %u\n",
           cpu_family, cpu_model, cpu_stepping);


    return 0;
}

However, Visual Studio 2013 is giving me an 'InteliSense: expected an expression' error for this line:

asm("movl %4, %%eax; cpuid; movl %%eax, %0; movl %%ebx, %1; movl %%ecx, %2; movl %%edx, %3;"
        : "=m" (result.eax), // <-- Error Here
          "=m" (result.ebx),
          "=m" (result.ecx),
          "=m" (result.edx)               /* output */
        : "r"  (number)                   /* input */
        : "eax", "ebx", "ecx", "edx"      /* no changed registers except output registers */
        );

As Visual Studio 2013 told me that error C2290: C++ 'asm' syntax ignored. Use __asm., I changed asm to __asm.

Every error I have is related to the above block of code:

5   IntelliSense: expected a ')'
Error   2   error C2290: C++ 'asm' syntax ignored. Use __asm.   
Error   1   error C2143: syntax error : missing ')' before ':'
Error   3   error C2059: syntax error : ')'

As I'm literally using the code provided from the thread mentioned above without any alterations (apart from the __asm edit), I'm assuming that I'm not including a required library or header that doesn't need to be included in earlier versions of Visual Studio.

If so, what headers/libraries am I missing? If not, what am I doing wrong?

AStopher
  • 4,207
  • 11
  • 50
  • 75
  • 4
    There are different asm syntaxes. Yours seems to be for gcc ( correct me if im wrong ). [Here](http://msdn.microsoft.com/en-us/library/4ks26t93.aspx) you can read about what Visual Studio wants it to look like. – Slyps Sep 07 '14 at 14:54
  • 1
    Without bothering to debug, I assume your 'asm' syntax is wrong. According to [MSDN](http://msdn.microsoft.com/en-us/library/45yd4tzz.aspx), you should use "__asm" instead of "asm", use {} instead of (), and the commands should not be in quotes. – Ryan Bemrose Sep 07 '14 at 14:56
  • @RyanBemrose As mentioned in the question, I had changed `asm` to `__asm`, but I put the original code there for clarity. I'll edit it for `__asm`. – AStopher Sep 07 '14 at 14:57
  • @Slyps Please could you provide an answer with what the `__asm` code is supposed to look like under Visual Studio? – AStopher Sep 07 '14 at 15:00

1 Answers1

2

Your example code is using GCC-style inline assembly syntax which isn't supported by the Microsoft compiler. While Microsoft has it's own inline assembly syntax, you should avoid using it wherever possible. It's only supported with the 32-bit x86 compiler, it's not supported with the 64-bit compiler or compilers targetting AMD or other CPU architectures. Also unlike GCC's inline assembly syntax, Microsoft's syntax is subject a number of undocumented rules, and even if written "correctly" can be very fragile.

In your case you should be using Microsoft's intrinsic function for the CPUID instruction. It will work with both 32-bit and 64-bit versions of the compiler and won't break because you changed optimization levels or upgraded your compiler. The specific function you want to use is __cpuid. The linked documentation should make it clear how you can use it to replace the inline assembly statement in your cpuid function.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
  • The documentation from Microsoft doesn't seem to have any functions to obtain the CPU family. – AStopher Sep 07 '14 at 15:17
  • The `__cpuid` function can be used to obtain the CPU family just like in your example code. Just replace the inline assembly statement with a call to `__cpuid`. You'll need to pass an array to __cpuid. Copy the values in the array to the structure and return it. – Ross Ridge Sep 07 '14 at 15:24
  • The MSVC compiler defines a bunch of [constants](http://msdn.microsoft.com/en-us/library/b0084kay.aspx), including ones based on CPU arch. Should be able to use #ifndef _M_X86. – Ryan Bemrose Sep 07 '14 at 18:54
  • Also, http://stackoverflow.com/questions/152016/detecting-cpu-architecture-compile-time – Ryan Bemrose Sep 07 '14 at 18:55