我使用this forum topic中的代码来获取CPU的家庭信息:
#include <stdio.h>
struct cpuid_type {
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
};
typedef struct cpuid_type cpuid_t;
cpuid_t cpuid(unsigned int number)
{
cpuid_t result;
__asm("movl %4, %%eax; cpuid; movl %%eax, %0; movl %%ebx, %1; movl %%ecx, %2; movl %%edx, %3;"
: "=m" (result.eax),
"=m" (result.ebx),
"=m" (result.ecx),
"=m" (result.edx) /* output */
: "r" (number) /* input */
: "eax", "ebx", "ecx", "edx" /* no changed registers except output registers */
);
return result;
}
int main (int argc, const char * argv[])
{
cpuid_t cpuid_registers;
unsigned int cpu_family, cpu_model, cpu_stepping;
cpuid_registers = cpuid(1);
cpu_family = 0xf & (cpuid_registers.eax>>8);
cpu_model = 0xf & (cpuid_registers.eax>>4);
cpu_stepping = 0xf & cpuid_registers.eax;
printf("CPUID (1): CPU is a %u86, Model %u, Stepping %u\n",
cpu_family, cpu_model, cpu_stepping);
return 0;
}
然而,Visual Studio 2013给了我一个&#39; InteliSense:期待一个表达&#39;这一行的错误:
asm("movl %4, %%eax; cpuid; movl %%eax, %0; movl %%ebx, %1; movl %%ecx, %2; movl %%edx, %3;"
: "=m" (result.eax), // <-- Error Here
"=m" (result.ebx),
"=m" (result.ecx),
"=m" (result.edx) /* output */
: "r" (number) /* input */
: "eax", "ebx", "ecx", "edx" /* no changed registers except output registers */
);
由于Visual Studio 2013告诉我error C2290: C++ 'asm' syntax ignored. Use __asm.
,我将asm
更改为__asm
。
我遇到的每一个错误都与上面的代码块有关:
5 IntelliSense: expected a ')'
Error 2 error C2290: C++ 'asm' syntax ignored. Use __asm.
Error 1 error C2143: syntax error : missing ')' before ':'
Error 3 error C2059: syntax error : ')'
由于我真的使用上述线程提供的代码而没有任何更改(除了__asm
编辑),我假设我不包含必需的不需要包含在早期版本的Visual Studio中的库或标题。
如果是这样,我错过了哪些标题/库? 如果没有,我做错了什么?
答案 0 :(得分:1)
您的示例代码使用的是GCC样式的内联汇编语法,Microsoft编译器不支持该语法。虽然Microsoft拥有自己的内联汇编语法,但您应该尽可能避免使用它。它仅支持32位x86编译器,64位编译器或目标AMD或其他CPU架构的编译器不支持它。与GCC的内联汇编语法不同,Microsoft的语法受到许多未记录的规则的约束,即使“正确”编写也可能非常脆弱。
在您的情况下,您应该使用Microsoft的内部函数来执行CPUID
指令。它适用于32位和64位版本的编译器,并且不会因为您更改了优化级别或升级了编译器而中断。您要使用的具体功能是__cpuid
。链接的文档应该清楚说明如何使用它来替换{{1}}函数中的内联汇编语句。