2015-05-31 66 views
0

我想了解如何使用xmm寄存器比较两个浮点数(32位)。 为了测试我用C编写的代码(它调用了汇编代码):xmm,cmp两个32位浮点数

#include "stdio.h" 

extern int compare(); 

int main() 
{ 

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

    return 0; 
} 

这里是国内组装,我想测试。如果B <℃,在这种情况下,它确实 和代码应该返回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,符合市场预期。 有人知道它为什么这样表现吗?也许我没有使用正确的跳转说明。

回答

5

您希望使用JB和JA(跳转到下面/上面)指令而不是JL/JG。 COMISS指令设置标志,就好像它是两个无符号整数进行比较。这使得标志上的效果更简单。

的COMISS指令对标志的影响英特尔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.

+0

JE和JNE应该工作得过.. ..? – AR89

+0

@ AR89是。 ZF标志在相等时设置。 –

相关问题