1

I've spent the last 2 days to study AT&T inline assembly, but I'm having some problems converting this one:

static char vendername[50] = {0};
_asm {
    mov     eax, 0
    cpuid
    mov     dword ptr [vendername], ebx
    mov     dword ptr [vendername+4], edx
    mov     dword ptr [vendername+8], ecx
}

Here is my try:

static char vendername[50] = {0};
__asm__(
    "movl $0,%%eax \n"
    "cpuid \n"
    "movl %%ebx, %[vendername] \n"
    "movl %%edx, %[vendername+$4] \n"
    "movl %%ecx, %[vendername+$8] \n"
    :"=r"(vendername) //user vendername as output
    :[vendername]"m"(vendername) //use vendername as input
    :"eax","ebx","edx","ecx" // clobbers those regs
);

This code doesn't work, gcc give me the following errors:

error: undefined named operand ‘vendername+4’

and

error: undefined named operand ‘vendername+8’

How do I convert the code from Intel assembly to AT&T assembly?

jww
  • 97,681
  • 90
  • 411
  • 885
Luca D'Amico
  • 3,192
  • 2
  • 26
  • 38
  • You need to use `__asm__ __volatile__` to ensure the optimizer does not remove the call to `CPUID`. – jww Aug 19 '15 at 18:13
  • You don't need inline asm. MSVC and GNU compilers have builtins / wrappers already. **[Intrinsics for CPUID like informations?](https://stackoverflow.com/q/17758409)** – Peter Cordes Jul 05 '18 at 20:13

2 Answers2

3

Rule of thumb is, if you ever write a mov in inline asm you are probably doing it wrong :) The compiler can load/store values for you on its own, ie.

int dummy;
union {
    char text[12];
    struct {
        int ebx;
        int edx;
        int ecx;
    };
} vendorname;
__asm__(
    "cpuid \n"
    : "=b" (vendorname.ebx), "=d" (vendorname.edx), "=c" (vendorname.ecx), "=a" (dummy)
    : "a" (0)
);

Note that the case was complicated by having to interpret the 3 dwords as a string.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • Are you certain this is correct: *"if you ever write a mov in inline asm you are probably doing it wrong"*. I can only get some ASM code to work if its ***not*** Extended ASM. In the absences of Exteded ASM, it seems like you need to use `mov`. – jww Aug 19 '15 at 18:19
  • 1
    Sure, I meant extended asm, which should be kept small and most of the time can be described using the input/output mechanism so the compiler has flexibility in code generation instead of the programer hardcoding `mov`s that might not even be needed. – Jester Aug 19 '15 at 21:36
  • Ah, thanks. Sorry about some of these basic questions. I'm a security guy with programming background, but I lack expertise in some these areas. – jww Aug 19 '15 at 21:51
1

You can do it as:

#include <stdio.h>

int main(int argc, char **argv) {
  static char vendername[50] = {0};

  __asm__ __volatile__ (
    "movl $0, %%eax\n"
    "cpuid\n"
    "movl %%ebx, %0\n"
    "movl %%edx, %0 + 4\n"
    "movl %%ecx, %0 + 8\n"
    :"=m"(vendername)
    :
    :"eax", "ebx", "edx", "ecx"
  );

  printf("%s\n", vendername);

  return 0;
}