AStopher
AStopher

Reputation: 4520

Expected an expression in `__asm` statement

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?

Upvotes: 1

Views: 4096

Answers (1)

Ross Ridge
Ross Ridge

Reputation: 39551

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.

Upvotes: 2

Related Questions