Well I don?t think I am good with FPU instructions so I am asking you guys to, please, give me comments and your opinions about the below procedure. It converts an angle expressed in Degrees to an angle expressed in Cycles. I am using Double Precision Floating Point values here but I really do not know if what I am doing is an optimal way of calculating this value.

``; --------------------------------------------------%DEFINE     TBYTE     TWORD; --------------------------------------------------  __MathDegToCycle:    ; void __MathDegToCycle (const TBYTE* DegAngle, TBYTE* Result); StdCall;    ; Deg To Cycle = (Deg * PI/180) / (2 * PI)    PUSH    EAX                                 ; Push the accumulator onto the stack    PUSH    EBP                                 ; Push the base pointer onto the stack    MOV     EBP , ESP                           ; Move the stack pointer to the base pointer    SUB     ESP , 0x0000000A                    ; Allocate 10 bytes of the stack space for immediate float values    LEA     EAX ,                   ; *EAX = The allocated space in the stack    MOV     DWORD PTR  , 0x94E9C8AE        ; DWORD #0 of Extended Precision Floating Point value of (PI/180)    MOV     DWORD PTR  , 0x8EFA3512 ; DWORD #1 of Extended Precision Floating Point value of (PI/180)    MOV     WORD  PTR  , 0x3FF9     ; Last WORD of Extended Precision Floating Point value of (PI/180)    FLD     TBYTE PTR                      ; ST0 = PI/180 (Deg To Cycle = (Deg * (PI/180)) / (2 * PI))    FWAIT                                       ; Wait for the value to be loaded    MOV     EAX , DWORD PTR         ; *EAX = Points to the  parameter    FLD     TBYTE PTR                      ; ST0 = , ST1 = PI/180    FWAIT                                       ; Wait for the value of  to be loaded into the FPU    FMULP   ST1 , ST0                           ; ST0 =  * (PI/180) , ST1 = Free    FWAIT                                       ; Wait for the calculation to be completed by the FPU    LEA     EAX ,                   ; *EAX = Pointer to the stack allocated space    MOV     DWORD PTR  , 0x2168C235        ; DWORD #0 of Extended Precision Floating Point value of (2 * PI)    MOV     DWORD PTR  , 0xC90FDAA2 ; DWORD #1 of Extended Precision Floating Point value of (2 * PI)    MOV     WORD  PTR  , 0x4001     ; Last WORD of Extended Precision Floating Point value of (2 * PI)    FLD     TBYTE PTR                      ; ST0 = 2*PI, ST1 =  * (PI/180)    FWAIT                                       ; Wait for the value to be loaded into the FPU    FDIVP   ST1 , ST0                           ; ST0 = ( * (PI/180)) / (2 * PI) = DegAngle -> CyclesAngle    FWAIT                                       ; Wait for the computation to complete in the FPU    MOV     EAX , DWORD PTR         ; *EAX = Pointer to the  parameter    FSTP    TBYTE PTR                      ; Store the result in the  parameter; ST0 = Free    ADD     ESP , 0x0000000A                    ; Deallocate 10 bytes of the stack space    POP     EBP                                 ; Restore the base pointer    POP     EAX                                 ; Restore the accumulator    RET     0x08                                ; Return to the calling procedure                                                ; And sweep 2 parameter off the stack``
Posted on 2007-03-26 05:00:30 by XCHG
``MathDegToCycle proc uses eax pDegree:ptr real8,pResult:ptr real8	mov eax,pDegree	.data		fOneOver360 QWORD 3F66C16C16C16C17h ; = 1/360, maximum precision	.code	fld real8 ptr 	mov eax,pResult	fmul fOneOver360	fstp real8 ptr		retMathDegToCycle endp``
Posted on 2007-03-26 05:48:00 by Ultrano
Ultrano,

That was one hell of a solution. Thank you so much but I don't seem to be able to get the difference between extended precision and doubles. Which one is which? Where am I? Who are you?
Posted on 2007-03-26 09:37:57 by XCHG
That 8-byte value - I got it directly with
``.datatemp real4 360.0.codefld1fdiv tempfstp fOneOver360 ; the variable is actually a "real8"``

Otherwise, if you simply put such a value as 0.0027777777777777777777777777, the assembler might lose a bit of precision.

Probably you'll need to change "real8" to TBYTE  (real10) from the code I posted. Some FPU instructions can't handle real10 data, so I never use real10.
Posted on 2007-03-26 10:25:36 by Ultrano
in C/C++,
float: 4 bytes
double : 8 bytes
long double : 10 bytes

in asm
real4 / dd / DWORD
real8 / dq / QWORD
real10/ dt / TBYTE
Posted on 2007-03-26 10:38:41 by Ultrano
Just checked MSDN 2005, and... in VS2k5 "long double" is 8 bytes instead of 10. (and there's no alternative for 10-byte floats) Perhaps it's done in order to simplify the compiler's optimization routines.
Posted on 2007-03-26 10:47:07 by Ultrano

in C/C++,
float: 4 bytes
double : 8 bytes
long double : 10 bytes

not true. Types in C are not quaranteed to have any size (some have quaranteed minimal size). All you know is that  sizeof(long double) >= sizeof(double) >= sizeof(float).

You should define your own types when you need data of exact size
Posted on 2007-03-26 12:24:49 by vid
Afaik Microsoft dropped REAL10 support quite a while ago... probably as long ago as VC6.
Posted on 2007-03-26 17:10:10 by f0dder