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 flagszf
,pf
, ,cf
ineflags
register according result.
thefcomi/fcomip
,fucomi/fucomip
instructions setof
,sf
,af
flags 0 ineflags
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
Post a Comment