x86 - nasm compare floating point values -


i've been trying hours now, don't understand why doesn't work. code use , never goes sort.swap.

sort:   ; ... .inner1   ; load data[i] st0 .inner2   ; load data[j] st0, data[i] in st1 .test:   fcomi      ; compare st0 (data[j]) st1 (data[i]), status on cpu   fcom       ; same, on fpu status flag (just compare in gdb)   jl .swap   ffreep st0 ; pop st0 (data[j])   jmp .inner2 .swap:   ; ... 

and in gdb do

b sort.test r si   // fcomi si   // fcom float r 

sample output 1

this 1 behaves expected, think, because 0.5327 not smaller 0.5262, therefore should not go sort.swap.

(gdb) b sort.test breakpoint 1 @ 0x804881b (gdb) r starting program: /home/niklas/desktop/erapraktikum/ss15-g52/projekt1/implementierung/build/read -v ../testdaten/zufall-100.txt reading input files ../testdaten/zufall-100.txt ... read 100 entries. calc.asm: calc(100, 0x804c170, 0x804d178, 0x804e180, 0x804f188)  breakpoint 1, 0x0804881b in sort.test () (gdb) si 0x0804881d in sort.test () (gdb) si 0x0804881f in sort.test () (gdb) disass dump of assembler code function sort.test:    0x0804881b <+0>:     fcom   %st(1)    0x0804881d <+2>:     fcomi  %st(1),%st => 0x0804881f <+4>:     jl     0x8048825 <sort.swap>    0x08048821 <+6>:     ffreep %st(1)    0x08048823 <+8>:     jmp    0x8048801 <sort.inner2> end of assembler dump. (gdb) float   r7: valid   0x3ffe86b87e0000000000 +0,5262526273727416992      =>r6: valid   0x3ffe8862d40000000000 +0,5327579975128173828        r5: empty   0x00000000000000000000   r4: empty   0x00000000000000000000   r3: empty   0x00000000000000000000   r2: empty   0x00000000000000000000   r1: empty   0x00000000000000000000   r0: empty   0x00000000000000000000  status word:         0x3020                  pe                                                top: 6 control word:        0x037f   im dm zm om um pm                        pc: extended precision (64-bits)                        rc: round nearest tag word:            0x0fff instruction pointer: 0x00:0x0804881d operand pointer:     0x00:0x0804e184 opcode:              0x0000 (gdb) r eax            0x804e184        134537604 ecx            0x1      1 edx            0x0      0 ebx            0x5573e000       1433657344 esp            0xffffc868       0xffffc868 ebp            0xffffc878       0xffffc878 esi            0x804e30c        134537996 edi            0x0      0 eip            0x804881f        0x804881f <sort.test+4> eflags         0x202    [ if ] cs             0x23     35 ss             0x2b     43 ds             0x2b     43 es             0x2b     43 fs             0x0      0 gs             0x63     99 (gdb) si 0x08048821 in sort.test () (gdb) disass dump of assembler code function sort.test:    0x0804881b <+0>:     fcom   %st(1)    0x0804881d <+2>:     fcomi  %st(1),%st    0x0804881f <+4>:     jl     0x8048825 <sort.swap> => 0x08048821 <+6>:     ffreep %st(1)    0x08048823 <+8>:     jmp    0x8048801 <sort.inner2> end of assembler dump. 

sample output 2

here however, would've expected jump sort.swap since 0.4657 smaller 0.5262. doesn't.

(gdb) disass dump of assembler code function sort.test: => 0x0804881b <+0>:     fcom   %st(1)    0x0804881d <+2>:     fcomi  %st(1),%st    0x0804881f <+4>:     jl     0x8048825 <sort.swap>    0x08048821 <+6>:     ffreep %st(0)    0x08048823 <+8>:     jmp    0x8048801 <sort.inner2> end of assembler dump. (gdb) si 0x0804881d in sort.test () (gdb)  0x0804881f in sort.test () (gdb) float   r7: valid   0x3ffe86b87e0000000000 +0,5262526273727416992      =>r6: valid   0x3ffdee7c3c0000000000 +0,4657915830612182617        r5: empty   0x00000000000000000000   r4: empty   0x00000000000000000000   r3: empty   0x00000000000000000000   r2: empty   0x00000000000000000000   r1: empty   0x00000000000000000000   r0: empty   0x00000000000000000000  status word:         0x3120                  pe             c0                                 top: 6 control word:        0x037f   im dm zm om um pm                        pc: extended precision (64-bits)                        rc: round nearest tag word:            0x0fff instruction pointer: 0x00:0x0804881d operand pointer:     0x00:0x0804e188 opcode:              0x0000 (gdb) r eax            0x804e188        134537608 ecx            0x2      2 edx            0x0      0 ebx            0x5573e000       1433657344 esp            0xffffc868       0xffffc868 ebp            0xffffc878       0xffffc878 esi            0x804e30c        134537996 edi            0x0      0 eip            0x804881f        0x804881f <sort.test+4> eflags         0x203    [ cf if ] cs             0x23     35 ss             0x2b     43 ds             0x2b     43 es             0x2b     43 fs             0x0      0 gs             0x63     99 (gdb) si 0x08048821 in sort.test () (gdb)  0x08048823 in sort.test () (gdb) disass dump of assembler code function sort.test:    0x0804881b <+0>:     fcom   %st(1)    0x0804881d <+2>:     fcomi  %st(1),%st    0x0804881f <+4>:     jl     0x8048825 <sort.swap>    0x08048821 <+6>:     ffreep %st(0) => 0x08048823 <+8>:     jmp    0x8048801 <sort.inner2> end of assembler dump. 

what reason , how can make work? thanks!

from description of jcc in volume 2 of intel's manual:

jl rel8   jump short if less (sf≠ of). 

and description of fcomi:

performs unordered comparison of contents of registers st(0) , st(i) , sets status flags zf, pf, , cf in eflags register according result.

the fcomi/fcomip , fucomi/fucomip instructions set of, sf , af flags 0 in eflags register

hence, sf equal of after fcomi, condition jl jumps never met.


based on table 3-31 in description of fcomi use jc jump if st(0) < st(i) (or jb, different name jc).


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

android - CollapsingToolbarLayout: position the ExpandedText programmatically -

Listeners to visualise results of load test in JMeter -