2
votes

I'm trying to convert a 32-bit float into an extended precision 80-bit float. I'm using MSVC x86. I tried the following inline ASM code:

void Convert32To80(float *value, void *outValue)
{
    __asm
    {
        fld float ptr [value];
        fstp tbyte ptr [outValue];
    }
}

Here, void *outValue is a buffer that is large enough to hold 10 bytes. This looks right to me, but it's crashing when it's run.

Any help is appreciated!

2
"crashing when run." What specific error(s) do you get? - James
I get no specific error. It's a C++/CLI dll which is loaded from managed code (it's something with the ASM, other inline ASM stubs work fine). I get this: "The runtime has encountered a fatal error. The address of the error was at 0x64f9fca1, on thread 0x1904. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack." - jakobbotsch
You need to check with your debugger which instruction causes the crash. Perhaps your outValue is bad (NULL or something like that)? - Suma
I tried that actually, but for some reason I can't step into the function. Not even in disassembly view. - jakobbotsch
@Jakob I bet you get no error because of the bone-headed decision of MS to run the FPU with the exception masks cleared! You're always much better off doing FP work with Borland tools. - David Heffernan

2 Answers

3
votes

OK, this should do it:

void Convert32To80(float *value, void *outValue)
{
    __asm
    {
        mov eax,dword ptr [value] 
        fld dword ptr [eax] 
        mov ecx,dword ptr [outValue] 
        fstp tbyte ptr [ecx] 
    }
}

All I did was wrote some C code to do the same, but for a float to double conversion, looked at the dissasembly and then modified as necessary.

Note that I am no expert with MSVC and I'm not 100% sure that I can use the EAX and ECX registers like that without saving/restoring them. Others may know more and offer corrections.

1
votes

Updated Note for posterity: Apparently, MSVC 2010 has no type for 80bit floating point types, so the obvious solution in C or C++ code along the lines of

float inValue = 666.666f;
long double outValue = (long double)inValue;

does NOT work, and you are actually forced to directly use assembly language.