flat assembler
Message board for the users of flat assembler.
Index
> Windows > FPU crashes with simple operations |
Author |
|
evk1 12 Dec 2014, 21:17
The problem is in square brackets. The instruction fld dword[eax] does not means to load eax value to the st0 register but means to load value from the memory location whose address is specified in eax (74) to the st0 register. Windows reserves low addresses for a system usage, so this line should generate something like General Protection Fault or Segmentation Fault. Unfortunately fld cannot loads values directly from general purpose registers, but you can use:
Code: value_to_load dd 74 ... fld dword [value_to_load] or: Code: pushd 74 fld dword [esp] ... fstp dword[esp] pop eax _________________ Sorry for my English |
|||
12 Dec 2014, 21:17 |
|
rinart73 12 Dec 2014, 21:36
Ok, thank you.
But... how should I store result of "fsin" in memory as float? :/ Code: section '.text' code executable start: ;; pushd 33 fld dword[esp] fsin fstp dword[esp] pop eax ;; push eax push format_f call [_printf] add esp, 8 call [_getchar] ;; invoke ExitProcess,0 section '.rdata' data readable writeable format_f db "%f",10,0 It writes 74842930642344961000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000.000000 Code: mov [n], 13 fld [n] fsin fstp [n] ;; push [n] ; or push n push format_f call [_printf] add esp, 8 call [_getchar] Result is 0.0000 |
|||
12 Dec 2014, 21:36 |
|
tthsqe 12 Dec 2014, 22:28
Code: push 13 ; push integer dword 13 onto memory stack fild dword[esp] ; load this integer into fpu stack fsin ; take sin(13)=0.4201 fstp dword[esp] ; pop 0.4201 off of fpu stack and put on stack in memory in the 4 byte locate created with push 13; this is the second argument of print_f push format_f ; this is the first argument of print_f call [_printf] Your code should also work if you change fld [n] to fild [n]; you need to tell fpu it to load [n] as an integer, (it does the int->float conversion automatically) |
|||
12 Dec 2014, 22:28 |
|
rinart73 12 Dec 2014, 23:39
I copied your code and get... :
74842945739140183000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000.000000 Code: mov [n], 13 fild [n] fsin fstp [n] ;; push n push format_f call [_printf 0.0000 Anyway :< |
|||
12 Dec 2014, 23:39 |
|
evk1 12 Dec 2014, 23:52
I don't understand it. sin should always return value between -1 and 1. It can be rounded to integers -1,1 and 0. But your code returns another values. Try adding finit, but I think it shouldn't help.
|
|||
12 Dec 2014, 23:52 |
|
evk1 12 Dec 2014, 23:56
In your latest code you should replace push n with pushd [n]. But, I think it will not solve the problem.
_________________ Sorry for my English |
|||
12 Dec 2014, 23:56 |
|
rinart73 12 Dec 2014, 23:59
finit - no result
pushd - no result How can I store calculated value from FPU to some variable or register correctly? Not a integer part, but all value? UPD: Ok, this CRAZY construction works(when i place "%d" in format). But not sin Code: finit pushd 13 ; push integer dword 13 onto memory stack fld dword[esp] ; load this integer into fpu stack fadd st0,st0 ; take sin(13)=0.4201 fstp dword[esp] ; pop 0.4201 off of fpu stack and put on stack in memory in the 4 byte locate created with push 13; this is the second argument of print_f pop dword[esp] mov eax, [esp] push eax push format_f ; this is the first argument of print_f call [_printf] add esp, 8 and this for [n]: Code: fld [n] fadd st0,st0 mov eax, n fstp dword[eax] Last edited by rinart73 on 13 Dec 2014, 00:22; edited 1 time in total |
|||
12 Dec 2014, 23:59 |
|
evk1 13 Dec 2014, 00:17
Hmm, 74842945739140183. 17 digits. It seems too large for a float mantissa. Are you sure you are using correct printf version?
|
|||
13 Dec 2014, 00:17 |
|
rinart73 13 Dec 2014, 00:24
Look at my prev. post. It works now... for %d
But I cant calculate sin, because resault will be 0 |
|||
13 Dec 2014, 00:24 |
|
evk1 13 Dec 2014, 00:29
Anyway, IIRC, so large mantissa cannot be used in float. I mean, maybe your printf treats floats as a doubles.
|
|||
13 Dec 2014, 00:29 |
|
rinart73 13 Dec 2014, 01:30
I think, yes
|
|||
13 Dec 2014, 01:30 |
|
tthsqe 13 Dec 2014, 04:04
no no. You didn't copy this code correctly. The second instruction should be FILD because you have to convert the integer to float
Code: push 13 ; push integer dword 13 onto memory stack fild dword[esp] ; load this integer into fpu stack (CONVERT FROM INT TO FLOAT) fsin ; take sin(13)=0.4201 fstp dword[esp] ; pop 0.4201 off of fpu stack and put on stack in memory in the 4 byte locate created with push 13; this is the second argument of print_f push format_f ; this is the first argument of print_f call [_printf] |
|||
13 Dec 2014, 04:04 |
|
rinart73 13 Dec 2014, 22:01
tthsqe,
1104150528 |
|||
13 Dec 2014, 22:01 |
|
RIxRIpt 13 Dec 2014, 22:35
printf %f requires double (64bit) values in stack.
Code: ;... sub esp, 8 fstp qword[esp] push format_f call [_printf] add esp, 12 http://stackoverflow.com/a/7197619/1901561 |
|||
13 Dec 2014, 22:35 |
|
tthsqe 13 Dec 2014, 22:43
rinart73, I hope you are not losing patience with this thing. It seems that the source of your errors are:
- confusing addresses for the values stored in the addresses - confusing integers with floating point values - giving printf a float (DWORD) when you should be giving it a double (QWORD). I think we might have to be a bit more explicit with RIxRIpt's suggestion: Code: push 13 fild dword[esp] fsin sub esp,4 ; make room for 8 byte double to be passed to printf fstp qword[esp] ; put the 8 byte double on stack push format_f call [_printf] |
|||
13 Dec 2014, 22:43 |
|
rinart73 13 Dec 2014, 23:54
Yeah! Thank you
|
|||
13 Dec 2014, 23:54 |
|
CampTheBoss 10 Mar 2015, 08:27
This might be an old post but..
the "%f" used in printf requires a quadword value. For example, floating 3 gives you "3.000" instead of random numbers which never change. |
|||
10 Mar 2015, 08:27 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.