Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

x87 FPOP and FCOM instructions - how do these work?

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!

like image 687
user905747 Avatar asked Aug 25 '11 18:08

user905747


People also ask

What are FPU registers?

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.

What is the maximum number of floating point arguments that can be passed between functions using the multimedia registers (% xmm0 to xmm15 )?

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.


1 Answers

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
like image 194
Jerry Coffin Avatar answered Sep 20 '22 14:09

Jerry Coffin