I've been tasked with writing a simple application in mixed C/ASM that has to use math coprocessor.
There's the function cylinder(float x, float y, float z) that returns 1 if the given point is within the cylinder (the cylinder has a base at x=0,y=0, radius = 5 and height = 10), and 0 if it isn't.
So, looks simple. Check whether z is within <0,10>, and then check if x^2 + y^2 < 25.
But my knowledge about x87 is nil.
There's everything I've written.
_cylinder PROC
push ebp
mov ebp, esp
sub esp,8 ; I can't use .data in the application, so I reserve some space on the stack for numbers 10 and 25
mov [esp],10
mov [esp+4],25
finit
fldz
fld [ebp+8]
;here i get stuck
add esp, 8
pop ebp
_cylinder ENDP
So I got stuck. So, I try to find what instructions could I use in the application. And there I get stuck, because every tutorial/instruction list i find on the net is written so badly I can barely understand anything.
The question is, what happens when I pop something from the math coprocessor? Where can I find the popped value? How does it converts from 80-bit value to 32 bit one (if it does, of course) Another question is, how does the FCOM (FCOMP for pop variant) works? It compares what to what ( st0 to st1 or st1 to st0?), and where can I see whether the value is smaller/equal/bigger?
Thanks for any help!
The floating-point register is used to execute the instruction. There are thirty-two 64-bit floating-point registers, numbered from floating-point register 0-31. All floating-point instructions provide a 5-bit field that specifies which floating-point registers to use in the execution of the instruction.
Up to eight floating point arguments can be passed in XMM registers %xmm0–%xmm7. These registers are used in the order the arguments are listed. Additional floating-point arguments can be passed on the stack. A function that returns a floating-point value does so in register %xmm0.
Floating point comparisons are kind of a pain. You can do the comparison on the FPU, but before you can do anything based on that, you have to transfer the floating point status word to the CPU, test for the flags you care about, and then react based on that.
Just for example, your initial comparison that z>=0.0 would look something like this:
fldz
fcomp z
fnstsw ax
test ah, 041h; I *think* I've got the right flags there...
jp good
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With