News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

64 bit and REAL10 values

Started by Gunther, September 23, 2012, 11:44:10 PM

Previous topic - Next topic

Gunther

At the moment I've only running a 64 bit Linux system. In a few weeks I'll buy a new machine with, at least, Windows 7 (64 bit). So, what's the question. Is it possible to work with REAL10 values (long double) under 64 bit Windows? The libc of Microsoft Visual C doesn't support that data type.

Gunther
You have to know the facts before you can distort them.

jj2007

AFAIK with 32-bit code, the FPU remains "as is", so no problem. With 64-bit code, no idea.
Attention with xmm regs: perfectly working 32-bit code with SSE2 may mysteriously fail on a 64-bit OS because some XMMs are being trashed by Win API calls.

qWord

The FPU is still available for ring3 applications. As for x32, all FPU registers are volatile; the stack must be empty before calling functions.
MREAL macros - when you need floating point arithmetic while assembling!

Gunther

Hi qword,

Quote from: qWord on September 24, 2012, 01:19:39 AM
The FPU is still available for ring3 applications. As for x32, all FPU registers are volatile; the stack must be empty before calling functions.

that's clear. But how is, for example, to print such a REAL 10 value? The printf doesn't work, because it uses the Windows libc.

Gunther
You have to know the facts before you can distort them.

qWord

Quote from: Gunther on September 24, 2012, 07:41:35 AMBut how is, for example, to print such a REAL 10 value? The printf doesn't work, because it uses the Windows libc.
You need to roll your own or translate existing code (e.g. fpulib) - but maybe some has already done this...
MREAL macros - when you need floating point arithmetic while assembling!

MichaelW

#5
I have tried multiple times before to find a CRT where printf properly supported REAL10, that could be reasonably used from a Windows app coded in MASM. This time I tried the CRT from the lcc-win compiler system, that I got here:

http://www.cs.virginia.edu/~lcc-win32/

The good parts are that the CRT printf (and related) functions do support long double, and that the CRT appears to be, at least functionally, encapsulated in a DLL. The not so good part is that I don't see a full 19 digits of precision.

;==============================================================================
; Build as a console app.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
    hMod dd 0
    r8   REAL8 ?
    r10  REAL10 ?
.code
;==============================================================================
start:
;==============================================================================
    invoke LoadLibrary, chr$("C:\lcc\bin\lcclibc.dll")
    mov hMod, eax
    printf("%Xh\n",hMod)
    invoke GetProcAddress, hMod, chr$("_printf")
    mov ebx, eax
    printf("%Xh\n\n",ebx)
    printf("3.141592653589793238462...\n")
    fldpi
    fstp r10
    fldpi
    fstp r8
    printf("%.20f\n",r8)
    push DWORD PTR r10+8
    push DWORD PTR r10+4
    push DWORD PTR r10+0
    push cfm$("%.20Lf\n\n")
    call ebx
    add esp, 16
    inkey
    exit
;==============================================================================
end start


10000000h
10008544h

3.141592653589793238462...
3.14159265358979310000
3.14159265358979324000


For reference, with an old DOS version of Turbo C I got:

3.14159265358979324000

And with a Digital Mars C/C++ compiler from 2007 (which used its own CRT instead of MSVCRT):

3.14159265358979323850

A few details that I noticed in doing this:

Long double is supported under Win64, but instead of the size being 12 bytes as it is for Win32 it had to be increased to 16 bytes.

Although not built in, there is support for a "qfloat" 352-bit floating-point type.
Well Microsoft, here's another nice mess you've gotten us into.

Gunther

Hi Michael,

thank you for the hint. I'll give it a try.

Quote from: MichaelW on September 24, 2012, 10:10:39 AM
Long double is supported under Win64, but instead of the size being 12 bytes as it is for Win32 it had to be increased to 16 bytes.

It's the same in 64 bit Linux. It seems that the 16 byte size is for alignment reasons.

Gunther
You have to know the facts before you can distort them.