根据主题,我遇到了问题。
在xmm0寄存器中,我有一个值,例如-512.000000
在xmm4:0.000000
。
我尝试将第一个值与零进行比较,但我无法实现这一点。
comisd xmm0, xmm4
COMISD
指令以奇怪的方式设置标志,并且只有jnz
之后才能在我的代码中正常工作。
我该如何进行这种比较?
答案 0 :(得分:6)
英特尔的手册文档COMISD
如何设置标记。
首先,使用jp
检查无序(如果您希望代码对NaN输入正常工作)。
然后,您可以使用任何ja
/ jae
/ jb
/ jbe
(上/下)条件或其否定值(jna
等),或je
/ jne
(等于/不等于)。这些条件与无符号整数比较的条件相同。显然cmov和setcc也有效。
这些条件具有jc
之类的同义词(如果CF == 1则跳转),但上/下具有正确的语义含义,因此可以减少使代码具有人类可读性所需的注释量。
您可以在jp
之类的条件之前跳过ja
,因为CF = 0意味着PF = 0。 (即如果操作数是无序的,a
条件将为假。对于无序操作数,某些其他条件(如ae
)将为真,因此您需要在jp
之前或之后分支如果您需要排除NaN输入,请jae
。
请注意,comisd
的标记设置与您从x87 fcom
/ fnstsw ax
/ sahf
获得的内容相匹配。另见this x87 tutorial/guide for an example of using that sequence。但仅限于历史兴趣! fcomi
,也以相同的方式设置标志,已存在超过20年(P6),并且更快。 (有关更多链接,请参阅x86标记wiki。)
x87仅对80位扩展精度有用,因为即使在32位模式下,也可以安全地假设SSE2可用。
答案 1 :(得分:3)
这里有Intel's IA-32 manual。 在页面689是COMISD说明,它指出:
RESULT ← OrderedCompare(DEST[63:0] ≠ SRC[63:0]) {
(* Set EFLAGS *) CASE (RESULT) OF
UNORDERED: ZF,PF,CF ← 111;
GREATER_THAN: ZF,PF,CF ← 000;
LESS_THAN: ZF,PF,CF ← 001;
EQUAL: ZF,PF,CF ← 100;
ESAC;
OF, AF, SF ← 0; }
同样在第178页,描述了哪个跳转指令基于EFLAGS注册商的哪个标志(EFLAGS在第78页描述)。
JC(如果进位则跳转)只检查CF标志是否设置 - 如果是,它可以少于关系或无序。
编辑: - 删除了错误的答案,不误导任何人留下手册的链接。
答案 2 :(得分:2)
COMISD的一个常见问题是它以与普通比较略有不同的方式设置标志。因此,COMISD将设置如下:
大于:ZF:0,PF:0,CF:0
等于:ZF:1,PF:0,CF:0
小于:ZF:0,PF:0,CF:1
因此,要测量XMM0是否小于XMM4,您需要进行JC。
相信这有帮助。