I was reading a bit of inline assembler the other day, and I saw
something in it that I didn't understand. Here's the code:
#define __cpuid(level, a, b, c, d) \
__asm__ __volatile__ ("xchg{l}\t{%%}ebx, %k1\n\t" \
"cpuid\n\t" \
"xchg{l}\t{%%}ebx, %k1\n\t" \
: "=a" (a), "=&r" (b), "=c" (c), "=d" (d) \
: "0" (level))
At first blush, looks pretty basic. Input values here, output values
there, constraints blah blah blah.
But what caught my eye was this bit in the actual assembler: %k1
Now, I know about letters that can be used in input/output constraints.
And I know about how %digits get replaced in the asm string. But I
wasn't aware of any qualifiers(?) that could be embedded into the asm
statement's arguments. I'm not seeing anything in the docs about it
either.
Q1: So what's the difference between %k1 and just %1?
FWIW, here's the asm that gets output from -S:
xchgl %ebx, %r8d
cpuid
xchgl %ebx, %r8d
Removing the 'k' seems to produce the same code, but the fact that
neither the compiler nor the assembler objects to having the k there
suggests that it means something to somebody.
Q2: And while I'm asking, what's with the {braces} in the asm?
I'm assuming those are an att thing (I'm an intel asm guy myself).
Because again, they are apparently being consumed by the compiler (-S
doesn't show them). I thought that "[the compiler] does not parse the
assembler instruction template and does not know what it means or even
whether it is valid assembler input." Isn't -S just the output that is
being sent to the assembler? Because it seems more is happening here
than simply writing the unparsed string to the asm file.
Q3: So are the docs wrong, and the c++ compiler really is parsing the
asm (beyond just for the purpose of replacing the arguments)?
Using rubenvb-4.8.0 on x64.
Thanks,
dw