我有struct
:
typedef struct {
unsigned int EAX;
unsigned int EBX;
unsigned int ECX;
unsigned int EDX;
} CPUIDinfo;
struct
用于函数:
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"
);
}
汇编程序正确匹配读取(%0
和%1
),但它与正确的写入不匹配。撰写时,使用{%0
,%1
,%2
,%3
}而不是{%2
,%3
,%4
,%5
}。这意味着info->EAX
被分配func
,info->EBX
被分配subfunc
,info->ECX
获得应该被放置在info->EAX
等等。
从Extended ASM manual开始,我知道汇编程序有名称限制:
"mov %[func], %%eax ;\n"
"mov %[subfunc], %%ecx ;\n"
但是当我尝试使用它时收到错误:
error: undefined named operand 'func'
error: undefined named operand 'subfunc'
我还试图告诉汇编程序在哪里使用:
: [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"
但这会导致更多错误,例如:
error: expected identifier before numeric constant
error: expected ']' before numeric constant
error: expected string-literal before numeric constant
如何匹配我的操作数,以便写入(例如mov %%eax, %2
)按预期执行?
答案 0 :(得分:2)
使用正确的寄存器约束,您的函数可能如下所示:
void get_cpuid_info(CPUIDinfo *info, const unsigned int func, const unsigned int subfunc)
{
__asm__ __volatile__ (
"cpuid"
: "=a"(info->EAX), "=b"(info->EBX), "=c"(info->ECX), "=d"(info->EDX)
: "a"(func), "c"(subfunc)
);
}
但要解决您的特定问题:应在约束中指定要使用的名称。那不是你应该写的[0]"m"(func), [1]"m"(subfunc)
:
[func] "m" (func), [subfunc] "m" (subfunc)
和输出约束类似。整个业务的重点是摆脱数字。您应该将符号名称放在方括号内,并将值放在圆括号中。