xmm,cmp两个32位浮点数

时间:2015-05-31 21:38:12

标签: assembly floating-point sse

我试图了解如何使用xmm寄存器比较两个浮点数(32位)。 为了测试我在C中编写了这段代码(在程序集中调用代码):

#include "stdio.h"

extern int compare();

int main()
{

    printf("Result: %d\n", compare());

    return 0;
}

这是装配,我想测试b< c,在这种情况下确实如此 并且代码应返回1,但它返回0:

section .data

a:  dd 5.5555
b:  dd 1.1111
c:  dd 5.5555

section .text

global compare

compare:
            ; -------------------------------------------
            ; Entrace sequence
            ; -------------------------------------------
            push    ebp         ; save base pointer
            mov     ebp, esp    ; point to current stack frame 
            push    ebx         ; save general registers
            push    ecx
            push    edx
            push    esi         
            push    edi

            movss xmm0, [b]
            movss xmm1, [c]
            comiss xmm0, xmm1
            jl change
            mov eax, 0
            jmp end
change:
            mov eax, 1
end:
            ; ------------------------------------------
            ; Exit sequence
            ; ------------------------------------------

            pop     edi
            pop     esi
            pop     edx
            pop     ecx
            pop     ebx
            mov     esp, ebp
            pop     ebp
            ret

如果我尝试使用jg它返回1,但我认为它应该相反,xmm0小于xmm1。

如果我写

movss xmm0, [b]
comiss xmm0, [b]
je change

按预期返回1。 有人知道它为什么会以这种方式行事吗?也许我没有使用正确的跳转说明。

1 个答案:

答案 0 :(得分:5)

您想要使用JB和JA(跳过下方/上方)指令而不是JL / JG。 COMISS指令将标志设置为两个无符号整数进行比较。这使得对标志的影响更简单。

COMISS指令对标志的影响记录在Intel 64和IA-32架构软件开发人员手册中:

RESULT ← OrderedCompare(SRC1[31:0] ≠ SRC2[31: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; }

虽然分支指令记录为:

77 cb    JA rel8   ...   Jump short if above (CF=0 and ZF=0).
72 cb    JB rel8   ...   Jump short if below (CF=1).
7F cb    JG rel8   ...   Jump short if greater (ZF=0 and SF=OF).
7C cb    JL rel8   ...   Jump short if less (SF≠ OF).

JB / JA测试根据操作结果设置的标志,而JL / JG测试标志始终设置为0。