assembly - xmm, cmp two 32-bit float -


i'm trying understand how compare 2 floating point numbers (32-bit) using xmm registers. test i've written code in c (which calls code in assembly):

#include "stdio.h"  extern int compare();  int main() {      printf("result: %d\n", compare());      return 0; } 

here assembly, want test if b < c, in case , code should return 1, returns 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 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 

if try use jg returns 1, think should opposite, xmm0 less xmm1.

if write

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

it return 1, expected. know why behaving in way? maybe i'm not using proper jump instructions.

you want use jb , ja (jump below/above) instructions instead of jl/jg. comiss instruction sets flags if 2 unsigned integers being compared. makes effect on flags simpler.

the comiss instruction's effect on flags documented in intel 64 , ia-32 architectures software developer’s manual as:

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; } 

while branch instructions documented as:

77 cb    ja rel8   ...   jump short if above (cf=0 , zf=0). 72 cb    jb rel8   ...   jump short if below (cf=1). 7f cb    jg rel8   ...   jump short if greater (zf=0 , sf=of). 7c cb    jl rel8   ...   jump short if less (sf≠ of). 

the jb/ja test flags set according the result of operation, while jl/jg test flags set 0.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -