I'm not sure and can't find nothing usable so I ask.
Is it necesary to preserve the FPU registers like CPU registers (ebx, edi, esi, etc.) when i use "stdcall" calling convention?  I guess not, but...

Posted on 2005-08-22 09:31:07 by Biterider
No, you are not required to preserve them. However it is possible (though I don't know of a case) where they may be affected by an API call, for example one that uses MMX commands. So you must consider them scratch registers and have no need to preserve them.
Posted on 2005-08-22 09:40:43 by donkey
OK, thanks!

Posted on 2005-08-22 09:43:35 by Biterider
donkey is right about FPU registers being considered as "scratch" registers. WinXP is known to use MMX commands in some of its APIs (cases have been observed and documented) and will destroy any valid data you may leave on the FPU if you call those APIs.

Although you don't have to preserve FPU registers in your procedures, you must always be aware of how many registers may be in use at any time if you are going to use FPU registers within different procedures of your app. Unless you design your app with great care, the best approach is to leave each procedure with a "clean" FPU (i.e. all registers "empty").

Posted on 2005-08-22 21:15:18 by Raymond

Unless you design your app with great care, the best approach is to leave each procedure with a "clean" FPU (i.e. all registers "empty").

Returning float results in ST(0) should be safe, though... as long as you don't call external code before using the returnvalue, of course :)
Posted on 2005-08-23 05:18:22 by f0dder
I know that this is an old thread, but I want to give a feedback on this topic.
Recently I was hit by this problem. An older application that ran perfectly for many years suddenly showed an erratic behaviour. I tracked down the problem to the corruption of the FPU stack after calling the LineTo API. This API never made a problem before until I ran the application on a new HP laptop. I guess it has something to do with the driver code that was called internally by the API code. The fact is that the internal FPU stack was changed after the API call and the remaining code failed.
I patched the code using FSAVE/FRSTOR and viola, all was fine again.
I learned that an existing code may fail if it doesn't follow exactly the rules. Unfortunately in this case, it is a relative unknown one.

Regards, Biterider
Posted on 2011-12-05 12:47:48 by Biterider
When Win98 was designed, the use of MMX registers was not yet known to MS programmers. All arithmetic operations were thus performed using the CPU registers.

When WinXP was designed (and maybe also Win2000), all required arithmetic operations (even if it was only 2+2 I think) were then performed using the MMX registers, trashing all the FPU registers in the process. Since APIs such as LineTo would definitely require some arithmetic operation, it is to be expected that it would trash the FPU registers.

Thus, any old application written for the Win98 (or earlier) OS relying on the FPU registers not being affected by API calls are at high risk of not performing correctly.

OTOH, prior to WinXP, an app would crash if the ESI and EDI registers were not preserved for the OS. This seems to have been corrected with WinXP and later which don't seem to rely anymore on users to preserve those registers.
Posted on 2011-12-05 13:51:51 by Raymond