Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I have specific problem: somewhere in my code there's something that causes FPU exception when converting. It doesn't matter what am I converting or to what is it being converted, it just causes exception.
Whenever I try to do something with resulting value (for example when I compare it), another exception is thrown. I'm using bochs and I don't know how to debug which exception has been thrown, because exception doesn't stop execution. I think that raw content of stack is 0 (I tried to print it), but I'm not sure.
Does anybody have any idea what can cause such behaivor when converting? Is there any way for stopping it? I have read something about exception masking in control word, but converted value will be still incorrect, won't it?
Please help.
Last edited by HugeCode on Thu Jul 18, 2013 2:25 am, edited 1 time in total.
Unless you want all FPU errors routed over the PIC chip, start with fixing your processor control registers (it's in CR0 - forgot the bit's actual name).
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
The FPU has a "tag word" that says what is in each register. The default value for the tag word (e.g. after power up/reset) is 0x5555, which says "all registers contain a special value". If you try to load anything into an FPU register, you will get an "invalid operation; floating point register stack overflow" exception because the register is not marked as "empty" in the tag word.
The FPU also has a "control word". The default value of the control word (e.g. after power up/reset) is 0x0040; which says "precision exception masked, no other exceptions masked, single precision, round to nearest".
Before using the FPU you have to initialise the FPU. This includes doing a "fninit" instruction, which will set the tag word to 0xFFFF ("all registers are empty"); and should also include setting the control word (e.g. set it to something like "precision exception masked, denormal operand exception masked, underflow exception masked, no other exceptions masked, double extended precision, round to nearest").
In addition to that; Combuster is right - unless you have to deal with old CPUs (80386 or older, where the FPU isn't built into the CPU and therefore "native FPU exceptions" isn't supported); you should enable "native FPU exceptions" in CR0. If you don't do this, FPU exceptions get routed through the PIC chip to IRQ 13 (which is slow, ugly, has some race conditions, and doesn't work at all when there's multiple CPUs); and if you do enable "native FPU exceptions" then you get a normal exception (interrupt 16) instead.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.