xmm,cmp两个32位浮点数

AR8*_*R89 0 floating-point assembly sse

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

#include "stdio.h"

extern int compare();

int main()
{

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是程序集,我想测试是否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
Run Code Online (Sandbox Code Playgroud)

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

如果我写

movss xmm0, [b]
comiss xmm0, [b]
je change
Run Code Online (Sandbox Code Playgroud)

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

Ros*_*dge 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; }
Run Code Online (Sandbox Code Playgroud)

虽然分支指令记录为:

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).
Run Code Online (Sandbox Code Playgroud)

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