assembly - Intel x86_64 程序集比较带符号的 double float

标签 assembly x86-64 intel precision sse

根据主题,我遇到了问题。

在 xmm0 寄存器中我有一个值,例如-512.000000
在 xmm4 中:0.000000

我尝试将第一个值与零进行比较,但我无法真正做到这一点。

comisd xmm0, xmm4

COMISD 指令以一种奇怪的方式设置标志,只有 jnz 之后才能在我的代码中正常工作。

我该如何进行比较?

最佳答案

Intel 的手册文档如何COMISD设置标志。

首先,使用 jp 检查无序(如果您希望您的代码对 NaN 输入正常工作)。

然后你可以使用任何 ja/jae/jb/jbe (上/下)条件或其否定(jna 等),或 je/jne(等于/不等于)。这些与无符号整数比较的条件相同。显然 cmovcc 和 setcc 也可以工作。

这些条件有类似 jc 的同义词(如果 CF==1 则跳转),但 above/below 具有正确的语义,因此可以减少使代码易于阅读所需的注释量.

您可以跳过像 ja 这样的条件之前的 jp,因为 CF=0 意味着 PF=0。 (即,如果操作数是无序的,则 a 条件将为假)。

一些其他条件,如 b(下面:CF=1)或 be(CF=1 或 ZF=1),对于无序操作数为真,因此如果您需要排除 NaN 输入,则需要在 jb/jbe 之前或之后在 jp 上分支。

如果我的逻辑正确,您可以反转比较操作数以允许使用 ja 而不是 jbe(例如)并将无序情况与其他“方式”分组。


历史意义/为什么这样设计:

请注意,comisd 的标志设置与您从 x87 fcom/fnstsw ax 获得的设置相匹配/sahf .另见 this x87 tutorial/guide for an example of using that sequence .但仅出于历史兴趣! fcomi ,它也以相同的方式设置标志,已经存在了 20 多年 (P6),而且速度更快。 (有关更多链接,请参阅 标签 wiki)。

x87 仅对 80 位扩展精度有用,因为通常可以安全地假设 SSE2 可用,即使在 32 位模式下也是如此。

另见 Why do x86 FP compares set CF like unsigned integers, instead of using signed conditions?更详细地了解为什么 x87 使用这些标志,fcomi 和 SSE 保持与这些标志的兼容性。

关于assembly - Intel x86_64 程序集比较带符号的 double float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37766131/

相关文章:

performance - 高效地反转 64 位字中 16 位数量的顺序

c - 为什么这个生成的汇编代码看起来包含废话?

c - 当我使用内核调试器在 Windows 64 位上的 SYSCALL 的 IA32_LSTAR MSR 上设置断点时,为什么会出现 DoubleFault? (KVASCODE 部分)

assembly - 组装远调用或远跳转(j* 指令)

c - 如何判断使用哪个版本的英特尔编译器来编译二进制文件

c - 通过指向 avr 程序集中数组的指针访问数组

汇编 MOV 指令操作数

c++ - Eclipse反汇编 View ,可以在不调试程序的情况下查看反汇编吗?

debugging - 英特尔AT&T汇编程序的分步执行?

assembly - x86 汇编程序崩溃,可能忽略简单错误