2015-05-31 88 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標誌在相等時設置。 –

相關問題