c++ - 预期 `__asm` 语句中的表达式

标签 c++ assembly visual-studio-2013 compiler-errors cpuid

我正在使用来自 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 给我一个“InteliSense: expected an expression”错误:

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 ig​​nored。使用__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 中。

如果是这样,我缺少哪些 header /库? 如果不是,我做错了什么?

最佳答案

您的示例代码使用的是 Microsoft 编译器不支持的 GCC 样式的内联汇编语法。虽然 Microsoft 有自己的内联汇编语法,但您应该尽可能避免使用它。它仅受 32 位 x86 编译器支持,不支持 64 位编译器或针对 AMD 或其他 CPU 架构的编译器。此外,与 GCC 的内联汇编语法不同,Microsoft 的语法受许多未记录的规则约束,即使“正确”编写也可能非常脆弱。

在您的情况下,您应该为 CPUID 指令使用 Microsoft 的内部函数。它适用于 32 位和 64 位版本的编译器,并且不会因为更改优化级别或升级编译器而中断。您要使用的具体功能是__cpuid .链接的文档应该清楚地说明如何使用它来替换 cpuid 函数中的内联汇编语句。

关于c++ - 预期 `__asm` 语句中的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25711263/

相关文章:

c# - WPF 旋转的 TextBlock 看起来不清楚

c++ - 在VS2010错误值中调试cpp

c++ - 在Qt中插入数据库

assembly - 故意在 RISC-V 中提出非法指令

assembly - 将二进制转换为十进制并在汇编中显示

c - 如何在C程序中打印堆栈的内容?

c++ - 结合 OpenMP、Intel MKL 和 MSVC 编译器时出现巨大内存泄漏

c++ - mmap如何分配超过20Gb?

c++ - 循环和奇怪的地址结果 C++

treeview - Visual Studio 2013 中的源代码管理资源管理器,保持最后一个树状态打开