首页 > 解决方案 > c 相当于 ucomisd

问题描述

在将 Windows 二进制文件移植到 linux 时,我遇到了以下一组指令:

ucomisd xmm5,xmm0
lahf 
test ah,0x44
jp 0x42D511

据我所知,它是比较 中的两个值ucomisd,然后测试是否存在ZForPF标志,但不能同时测试两者。

c等价物是什么?我对该主题进行的每一次搜索都会将浮点数/双精度数与 epsilon 进行比较,这显然没有这样做。

如果有帮助,第二个操作数始终是取自 .rdata 部分的 const 值。

标签: cx86

解决方案


ucomisd的伪代码似乎是

RESULT← UnorderedCompare(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; }

ZF xor PF如果 2 个双精度操作数相等,则为真。如果我没看错,这将是

double a, b;

if (a == b) {
    ...
}

如果操作码为零且奇偶校验标志未设置,则不会跳转,这就是需要lahf+test或其他替代方法的原因。

测试这个功能:

int x(double a, double b) {
    return a == b;
}

与 GCC 产生

xorl    %eax, %eax
movl    $0, %edx
ucomisd %xmm1, %xmm0

# set al to 1 if no parity flag
setnp   %al

# if zero flag not set, zero the return value
cmovne  %edx, %eax

ret

即如果没有奇偶校验标志并且相等则返回1。


推荐阅读