fstcw 汇编操作数类型不匹配

fstcw assembly operand type mismatch

我试图在 C 语言的内联汇编中使用指定的舍入模式对输入双精度值进行舍入。为此,我需要使用 fstcw 获取 FPU 控制字,然后更改位在这个词中。不幸的是,我在第一行遇到错误:

double roundD(double n, RoundingMode roundingMode) {
    asm("fstcw      %%ax       \n"

        ::: "ax");      //clobbers

    return n;
}

我收到的汇编错误是:

Error: operand type mismatch for 'fstcw'.

我的印象是此代码片段应将长度为 16 位的 FPU 控制字存储在长度也是 16 位的 AX 寄存器中。可以肯定的是,我还用 EAX 寄存器而不是 AX 测试了上面的代码,并收到了同样的错误。

我可能在这里遗漏了什么?如果需要任何进一步的信息,请告诉我。

fstcw(控制字)仅适用于内存目标操作数,不适用于寄存器。

也许您混淆了 fstsw(状态字),它具有单独的形式(单独的操作码),其中目的地是 AX 而不是由寻址模式指定。

这有助于基于 FP 比较结果(在 fcomi 比较存在 EFLAGS 之前)有效地进行分支,这比控制字的任何事情都更频繁。这就是为什么有 AX-destination 版本的 fnstsw 但没有 fnstcw.


顺便说一句,您可以使用 C 设置舍入模式。#include <fenv.h>

或者更好,如果 SSE4.1 可用,使用 roundsd(或固有的)以自定义舍入模式进行一次舍入,无需设置/恢复 SSE 舍入模式(在 MXCSR 中,完全与 x87 舍入模式分开。