【问题标题】:Windows / Intel Compiler / Inline Assembler & GNU syntax problemsWindows / Intel Compiler / Inline Assembler & GNU 语法问题
【发布时间】:2017-04-17 17:41:56
【问题描述】:

我有这个 C sn-p,它给出了一个编译器错误,我不知道为什么:

// 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 语法?

但是,我想避免总是在 ASM 语句周围使用 #ifdef,因为我们也使用 GCC。

【问题讨论】:

  • 您的代码是用 C 编写的还是用 C++ 编写的?请在两种语言中最多选择一种。
  • 内联汇编是特定于编译器的。如果你想避免一堆 ifdef,不要使用内联汇编。而是将汇编代码放在汇编文件中,并使用相同的汇编器来汇编它们,而不管您使用的是哪个 C 编译器。
  • 我无法重现您的错误。你能告诉我们生成的程序集吗?
  • 请注意,当您写入操作数时,它必须是输出操作数,而不是输入操作数。所以改写ASM("fnstcw %0" : "m"(mode))。可能这也解决了您的其他问题。
  • 那不是 C 代码。

标签: c++ gcc assembly intel


【解决方案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));

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

【讨论】:

  • 尽管出于兼容性原因,英特尔的编译器可以支持 GCC 样式或 MSVC 样式的内联汇编语法,但您几乎可以肯定想要使用 GCC 样式的语法,因为它是如此更强大(无论如何你都在写它!)。 MSVC 的语法无法指定输入值,因此它总是执行大量额外的存储和加载。
  • 我添加了 MSVC 样式只是为了看看它是否以这种方式工作,如前所述,ICC 支持两者。我想采用 GCC 风格。
  • @RobertM.Münch 你能告诉我生成的程序集吗?您可能需要对 ICC 使用 Intel 语法。幸运的是,有一种方法可以在 gcc 样式的 asm 语句中同时指定 AT&T 和 Intel 程序集。
猜你喜欢
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多