I have a struct
:
typedef struct {
unsigned int EAX;
unsigned int EBX;
unsigned int ECX;
unsigned int EDX;
} CPUIDinfo;
And that struct
is used in a function:
void get_cpuid_info(CPUIDinfo *info, const unsigned int func, const unsigned int subfunc)
{
__asm__ __volatile__ (
"push %%rax ;\n"
"push %%rcx ;\n"
"mov %0, %%eax ;\n"
"mov %1, %%ecx ;\n"
"cpuid ;\n"
"mov %%eax, %2 ;\n"
"mov %%ebx, %3 ;\n"
"mov %%ecx, %4 ;\n"
"mov %%edx, %5 ;\n"
"pop %%rcx ;\n"
"pop %%rax ;\n"
: "=m"(info->EAX), "=m"(info->EBX), "=m"(info->ECX), "=m"(info->EDX)
: "m"(func), "m"(subfunc)
: "%eax", "%ebx", "%ecx", "%edx"
);
}
The assembler is matching the reads correctly (%0
and %1
), but its not matching the writes correctly. When writing, its using {%0
, %1
, %2
, %3
} rather than {%2
, %3
, %4
, %5
}. That means info->EAX
gets assigned func
, info->EBX
gets assigned subfunc
, info->ECX
gets what should have been placed in info->EAX
, etc.
From the Extended ASM manual, I know the assembler has name constraints:
"mov %[func], %%eax ;\n"
"mov %[subfunc], %%ecx ;\n"
But I receive an error when I try to use them:
error: undefined named operand 'func'
error: undefined named operand 'subfunc'
I also tried to tell the assembler what to use where:
: [2]"=m"(info->EAX), [3]"=m"(info->EBX), [4]"=m"(info->ECX), [5]"=m"(info->EDX)
: [0]"m"(func), [1]"m"(subfunc)
: "%eax", "%ebx", "%ecx", "%edx"
But that results in more errors like:
error: expected identifier before numeric constant
error: expected ']' before numeric constant
error: expected string-literal before numeric constant
How can I match my operands so the writes (e.g., mov %%eax, %2
) perform as expected?