Author Topic: X64 ABI: how does a C compiler pass a REAL8?  (Read 1818 times)

tenkey

  • Regular Member
  • *
  • Posts: 39
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #15 on: April 15, 2021, 07:41:04 AM »
Do you have any opinions about whether MSVC interpreting plain int as a 32-bit integer (instead of a 64-bit integer in a 64-bit system) is correct or not?
We are also trying to say what "rcx (64-bit reg) contains the 1st argument" means. Does it mean the function expects the argument to always be a 64-bit value or not? The answer is "not always".

jj2007

  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #16 on: April 15, 2021, 08:25:48 AM »
Below a table by Martin Liversage in a reply to What is the bit size of long on 64-bit Windows? on SOF.

Looks simple, right? But M$ has 146 or so different data types to offer, see attachment, plus over 50 ways to execute the call instruction.

Re "correct": Google offers 9,650,000 answers for data types x86 x64. Pick the one that you like most :biggrin:

What do we really need?
chars
DWORDs
pointers
REAL4
REAL8

Plus every now and then a WORD or a QWORD :cool:

(I've marked in red the one type that is different in x86 vs x64)
« Last Edit: April 15, 2021, 10:10:48 AM by jj2007 »

HSE

  • Member
  • *****
  • Posts: 1743
  • <AMD>< 7-32>
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #17 on: April 15, 2021, 08:50:27 AM »
Hi JJ!

What do we really need?

You can follow Hutch' golden standard:

  qword
  sqword
  real8

Not just a coincidence is almost same as Unprototyped functions in x64 ABI (sqword and real8). That are the absolutly basics.

For most purposes you also can need others basics:

  byte
  sbyte
  word
  sword
  dword
  sdword
  real4

For very specifics and unusual purposes :

  fword
  oword
  real10

Everything else is one of previous one (perhaps a couple more in other processors:AVX, etc)

I'm wrong?  :biggrin:




jj2007

  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #18 on: April 15, 2021, 08:58:17 AM »
Right. You rarely need the signed/unsigned distinction, as most instructions don't care about the sign. A fild dword behaves like a fild sdword. The only exception are jumps resp .if .while .repeat ... .until (I use the signed equate a lot), but for the call instruction the sign is irrelevant.

The jinvoke version I'm working on will bark at you if you pass 11 or 13 parameters to CreateWindowEx, and it will throw an error if you pass a REAL8 to a function that expects a REAL4 (like many Gdi+ functions). All the rest boils down to RTFM :cool:

P.S.: The great majority of WINAPI calls in x64 still wants DWORDs, not QWORDs. Only pointers (and handles) require 64 bits.
Quote
You can follow Hutch' golden standard:

  qword
  sqword
  real8


HSE

  • Member
  • *****
  • Posts: 1743
  • <AMD>< 7-32>
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #19 on: April 15, 2021, 09:29:39 AM »
You rarely need the signed/unsigned distinction, as most instructions don't care about the sign.
You allow promotion, that it's important.

P.S.: The great majority of WINAPI calls in x64 still wants DWORDs, not QWORDs. Only pointers (and handles) require 64 bits.
For unsigneds is the same, but I'm reviewing that  :thumbsup: 
There is very clear concepts, but past never gone  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #20 on: April 15, 2021, 06:27:06 PM »
You rarely need the signed/unsigned distinction, as most instructions don't care about the sign.
You allow promotion, that it's important.

What do you mean with "promotion"?

The point with the signed/unsigned distinction is that it almost never matters:
Code: [Select]
include \Masm32\MasmBasic\Res\JBasic.inc ; OPT_64 1 ; put 0 for 32 bit, 1 for 64 bit assembly
MyUnsignedDword DWORD -12345
MySignedPointer SQWORD ?
.code
DefProc ShowTheArgs proc argString:QWORD, argSigned:SDWORD, argDouble:REAL8
  Inkey Str$("\nThe arguments:\n%s\n%i\n%f\n", argString, argSigned, argDouble)
  ret
ShowTheArgs endp
Init
  PrintLine Chr$("This program was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format.")
  mov rax, Chr$("Argument #1 is a string")
  mov MySignedPointer, rax ; oops, absolutely ILLEGAL!
  jinvoke ShowTheArgs, rax, MyUnsignedDword, FP8(33333.33333)
EndOfCode

Output:
Code: [Select]
This program was assembled with ml64 in 64-bit format.

The arguments:
Argument #1 is a string
-12345
33333.333330

We illegally assigned a negative value to MyUnsignedDword and to the string pointer, we illegally passed an unsigned DWORD to a proc that expects a SIGNED DWORD, and yet, the proc has no problem with that. We know why, the programmer of a HLL probably doesn't.

If you try the same game with REALs, trouble is ahead, because REAL4 and REAL8 are not at all compatible.

HSE

  • Member
  • *****
  • Posts: 1743
  • <AMD>< 7-32>
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #21 on: April 15, 2021, 09:39:24 PM »
What do you mean with "promotion"?

In HLL you can use a SBYTE arg to invoke a function that only read SDWORD. Compiler make transformation. Here invoke macro can make that, or you can make that manually before to invoke.  This transformation from a shorter type to a longer type is "promotion"

x64 ABI Unprototyped and Vararg functions very often require promotion.

Another strange HLL concept is "ellipsis", which apparently is similar to Vararg, but using the last declared type.

jj2007

  • Member
  • *****
  • Posts: 11551
  • Assembler is fun ;-)
    • MasmBasic
Re: X64 ABI: how does a C compiler pass a REAL8?
« Reply #22 on: April 15, 2021, 11:02:02 PM »
In HLL you can use a SBYTE arg to invoke a function that only read SDWORD

Thanks, got it. Something like movsx rax, al :cool: