1

I'm trying to compile this c source file using cl.exe (from Visual Studio). The specific code in question that fails to compile is:

#include <stdio.h>

static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
                                unsigned int *ecx, unsigned int *edx)
{
        /* ecx is often an input as well as an output. */
        asm volatile("cpuid"
            : "=a" (*eax),
              "=b" (*ebx),
              "=c" (*ecx),
              "=d" (*edx)
            : "0" (*eax), "2" (*ecx));
}

I'm seeing this failure:

C:\>cl sgx.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24213.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

sgx.c
sgx.c(7): error C2065: 'asm': undeclared identifier
sgx.c(7): error C2143: syntax error: missing ';' before 'volatile'
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
RobertJoseph
  • 7,968
  • 12
  • 68
  • 113
  • 3
    Looks like gcc extended inline asm. I don't think VS can understand it. Use a different compiler. – EOF Aug 29 '16 at 18:30
  • 2
    Have you tried `__asm` instead of `asm`? – David Ranieri Aug 29 '16 at 18:32
  • 3
    That appears to be GCC's extended inline assembler which is incompatible with MSVC. MSVC now has the compiler intrinsic `__cpuid` documented here: https://msdn.microsoft.com/en-us/library/hskdteyh.aspx . I'd convert your `cpuid` function to use the intrinsic instead of inline assembler. – Michael Petch Aug 29 '16 at 18:33
  • 1
    The typical MSVC syntax is `__asm { .... }` – Weather Vane Aug 29 '16 at 18:34
  • Your inline asm is GCC compatible. MS's is different. You'll have to convert syntax and the constraints. – Craig Estey Aug 29 '16 at 18:40
  • MSVC uses Intel syntax like `__asm { mov eax, 42 }` similar to MASM or TASM. – Weather Vane Aug 29 '16 at 18:49
  • When using `cpuid`, `eax` must be preset to the "command" value (e.g. 0 returns the processor id string like "Genuine Intel"), so you have to be careful. Also, MS asm doesn't have constraints like "=a", so you have to specify these manually, so I wouldn't inline the function as you don't know the regs to use. For a non-inline, from the MS ABI, the 64 bit mode args are (different than GCC): RCX,RDX,R8,R9 and RBX is callee preserved. See: https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx As others have said, use the __cpuid intrinsic [if you can] – Craig Estey Aug 29 '16 at 19:13
  • Correction accepted. My point still stands. All this goes away for example: https://msdn.microsoft.com/en-us/library/k1a8ss06.aspx – Peter Aug 30 '16 at 13:43

1 Answers1

4

Instead of direct assembly, you can use compiler intrinsics. Microsoft compilers support __cpuid() documented here: https://msdn.microsoft.com/en-us/library/hskdteyh.aspx

GCC instead supports __get_cpuid() via cpuid.h as described by this answer (https://stackoverflow.com/a/14266932/1401351).

Community
  • 1
  • 1
Peter
  • 14,559
  • 35
  • 55