【问题标题】:fstcw assembly operand type mismatchfstcw 程序集操作数类型不匹配
【发布时间】:2018-08-05 11:28:33
【问题描述】:

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

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

        ::: "ax");      //clobbers

    return n;
}

我收到的汇编错误是:

错误:“fstcw”的操作数类型不匹配。

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

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

【问题讨论】:

  • 所以我只是在谷歌上搜索了一下,显然fstcw 想要将内容存储在内存中,而不是寄存器中。
  • 根据this,目的地可以是内存中的某个位置,也可以是AX寄存器。
  • 不,你的链接正好相反:“fstcw Dest [...] 这条指令存储了控件的内容位于 16 位 WORD 内存地址 (Dest) 的字寄存器。" 和 "[fstsw] 是唯一可以将信息直接从 FPU 的一个寄存器传输到 CPU 的一个的 FPU 指令通用寄存器。".
  • 如果这恰好是船体速度分配,那么你可能想看看这个:stackoverflow.com/questions/35515378/…。如果船速分配对您毫无意义,那么该答案可能会给您一些信息。如果 hullspeed 任务是为了这个(我们最近有另一个 hullspeed 问题),那么这个答案可能会让你更感兴趣。

标签: c assembly rounding att x87


【解决方案1】:

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

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

这有助于根据 FP 比较结果有效地进行分支(在 fcomi 与 EFLAGS 进行比较之前存在),这比控制字的任何事情都更频繁地发生。这就是为什么有fnstsw 而不是fnstcw 的AX 目标版本。


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 2023-03-27
    • 2018-11-02
    • 2015-07-23
    相关资源
    最近更新 更多