assembly - 无效 'asm' : operand is not a condition code, 无效操作数代码 'c'

标签 assembly x86 g++ inline-assembly

我正在尝试从这里在 Linux 上构建 Voxlap https://github.com/Ericson2314/Voxlap当我尝试这样做时,我收到一条有关内联程序集的错误消息:

source/sdlmain.cpp: In function ‘void fpuinit(long int)’:
source/sdlmain.cpp:1814:3: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'
);
^

source/sdlmain.cpp:1814:3: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'
source/sdlmain.cpp:1814:3: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'
source/sdlmain.cpp:1814:3: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'

有问题的代码在这里:

static long fpuasm[2];
static inline void fpuinit (long a)
{
    __asm__ __volatile__
    (
        "fninit\n"
        "fstcww %c[fp]\n"
        "andb   $240, %c[fp]+1(,1)\n"
        "orb    %%al, %c[fp]+1(,1)\n"
        "fldcww %c[fp]\n"
        :
        : "a" (a), [fp] "p" (fpuasm)
        : "cc"
    );
}

编译器错误指向这部分

 : "cc"

任何破译错误消息或实际问题的帮助将不胜感激,谢谢

最佳答案

正如 Michael Petch 所解释的那样,问题的直接原因可能是因为 Ubuntu 现在附带了默认创建位置无关可执行文件 (PIE) 的 GCC 版本。当编译器生成位置无关代码 (PIC) 时,asm 语句不起作用。您可以用以下代码替换代码,因为它应该是等效的:

// set up the x87 FPU, ignoring the SSE MXCSR used for normal FP operations in x86-64 or 32-bit with -mfpmath=sse
static inline void fpuinit (long a)
{
    asm volatile (
        "mov %1, %0\n\t"
        "fninit\n\t"
        "fldcw %0\n"
        : "=m" (*(short *)fpuasm)    // *OUTPUT* operand, not input
        : "ir" ((short) (0x037F & 0xF0FF | (a & 0xFF) << 8)));
}

或者更好的是,分配给asm外部的fpuasm(如果您只想设置前2个字节,则使用memcpy),或者根本不分配,只使用本地tmp。 (两种方式的源+编译器生成的asm on the Godbolt compiler explorer )。这仍然有关于严格别名的警告,但至少我们告诉编译器这个函数写入fpuasm,而不是读取它。


这取代了笨拙的“p”“指针”约束和c“常量”操作数修饰符,它需要使其与简单的一起工作” m”“内存”约束。无论它是否被编译为 PIC,这都有一个优点。它还适用于 32 位和 64 位目标。

我还利用 FNINIT 指令将 FPU 控制字设置为已知状态 (0x037F) 的事实来优化代码,因此无需使用 FSTCW 指令来读取它。

使用两个内存目标 AND/OR 指令而不是在寄存器中准备值也是愚蠢的。

关于assembly - 无效 'asm' : operand is not a condition code, 无效操作数代码 'c',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42756765/

相关文章:

从 c 调用汇编函数导致段错误

x86 - DC PMM(内存模式)缓存​​一致性如何表现?

c++ - 未定义的行为或 gcc 优化错误

macos - 基本汇编程序上的 "Illegal instruction"- 甚至不是 hello world - 为什么需要链接?

c - MIPS 结构节点

Linux 上的 C++/汇编 IDE

linux - SYSENTER/SYSEXIT 与 INT 0x80

c++ - 使用 ostream 和 operator << 打印到控制台

c++ - 编译多个 C++ OpenGL

assembly - 关于intel汇编的问题