Windows / Intel编译器/内联汇编器& GNU语法问题

时间:2016-12-02 18:12:45

标签: c++ gcc assembly intel

我有这个C片段,它给出了编译错误,我不知道为什么:

// compiler dependent inline assemble 
#ifdef __INTEL_COMPILER
#define ASM __asm
#else
#define ASM __asm__
#endif

int getfpucw(
    /* Get FPU control word */
) {
    int mode = 0;

  // load mode value into register %0, no output ...: :...
    ASM fnstcw *&mode;
    ASM("fnstcw %0" : "m"(*&mode));
    return mode;
}

我明白了:

  

../ src / fpucw.c(28):错误:汇编语言中的无效常量   指令           ASM(“fnstcw%0”::“m”(*& mode));               ^

     

../ src / fpucw.c(28):错误:汇编语言中的无效常量   指令           ASM(“fnstcw%0”::“m”(*& mode));

第一个ASM声明通过。我想因为它是MS ASM语法?

但是,我想避免在我们使用GCC时始终在ASM语句中使用#ifdef。

1 个答案:

答案 0 :(得分:1)

我想我明白你的问题是什么:对于MSVC样式和gcc样式的程序集都有ASM指令,但是你总是包含它们。当然,icc被gcc风格的asm指令搞糊涂了,反之亦然。要解决此问题,我建议您重新定义ASM,如下所示:

#ifdef __INTEL_COMPILER
#define IASM(x) __asm x
#define GASM(x) 
#else
#define IASM(x)
#define GASM(x) __asm__(x)
#endif

然后更改你的asm指令:

IASM(fnstcw *&mode);
GASM("fnstcw %0" : : "m"(*&mode));

最后请注意,要使gcc样式的程序集指令正常工作,mode必须是覆盖其值时的输出操作数。因此,将该行更改为:

GASM("fnstcw %0" : "=m"(mode));

并注意*&是多余的,可以省略。