Author Topic: Difference between "Windows native" and "System V" x64 ABIs  (Read 11813 times)

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Difference between "Windows native" and "System V" x64 ABIs
« on: August 15, 2012, 10:25:51 PM »
Hello, I'm trying to determine the difference between these two 64-bit calling conventions:
  • Windows x64 calling convention (a.k.a. what MS calls "native").
  • x86-64.org "System V" calling convention:

The first convention is described in multiple articles, blogs, and documentation all over the internet.  It seems pretty simple:  There the first 4 arguments are passed in registers and additional arguments are passed on the stack.  As for the registers, there are 4 for integers and 4 for floating-point types.  The MS docs are really useful because they show examples like this:

Quote from: passing all integers
func1(int a, int b, int c, int d, int e); 
// a in RCX, b in RDX, c in R8, d in R9, e pushed on stack
Quote from: passing all floats
func2(float a, double b, float c, double d, float e); 
// a in XMM0, b in XMM1, c in XMM2, d in XMM3, e pushed on stack
Quote from: passing mixed ints and floats
func3(int a, double b, int c, float d); 
// a in RCX, b in XMM1, c in R8, d in XMM3


But for the 2nd convention, all there is is page 17 of http://www.x86-64.org/documentation/abi.pdf.  No examples or anything else that I can find except a tiny little thing here on slide 28 that only demonstrates a function with 2 args.

Can anyone give me a hand with a few examples of passing function args using the 2nd convention?  Either that or perhaps a good reference that explains it clearly?  I would appreciate it.
« Last Edit: August 16, 2012, 03:52:14 PM by hhh3h »

Offline Gunner

  • Jr. Member
  • *
  • Posts: 74
  • Country: us
    • Gunners Software
Re: Difference between Windows and standard x64 ABI
« Reply #1 on: August 15, 2012, 11:52:25 PM »
The first is used only in Windows API calls (and other internal Windows calls, or callbacks)

The second is used in many NON windows OS's.  Wiki explains calling conventions http://en.wikipedia.org/wiki/X86_calling_conventions. I prefer this one over they way Microsoft does it, as it uses more registers to pass params.

Microsoft:
Quote
The registers RCX, RDX, R8, R9 are used for integer and pointer arguments (in that order left to right), and XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional arguments are pushed onto the stack (right to left)

Linux (System V)
Quote
The registers RDI, RSI, RDX, RCX, R8, and R9 are used for integer and memory address arguments while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for floating point arguments. For system calls, R10 is used instead of RCX

Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 429
  • Country: us
Re: Difference between Windows and standard x64 ABI
« Reply #2 on: August 16, 2012, 03:42:36 AM »
The stack frame setup for a 64-bit Windows function call is nearly identical in concept to the 32-bit version.  Stack space is still allocated for the first four function parameters ( called register shadow space ).  It's a pretty clean mapping if you already know the C calling convention.

System V x64 ABI blows any pre-conceived notion of stack setup right out of the water.  Any knowledge you may have had previously regarding calling convention has been made obsolete.

Wiring in the NASMX source code portability to account for both Windows and Linux in either 32-bit or 64-bit was quite an undertaking mostly due to the x64 differences.

I flip back and forth between the two calling conventions when discussing which is better as each plays to the strengths of its respective target OS.

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: Difference between Windows and standard x64 ABI
« Reply #3 on: August 16, 2012, 07:34:43 AM »

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Re: Difference between "Windows native" and "System V" x64 ABIs
« Reply #4 on: August 27, 2012, 05:30:26 PM »
Thank you for the explaination. Sorry for the delay in responding but I have bought a book called Assembly Language Step By Step second edition by Duntermann. I'm about 1/3 done.  I know it won't cover this topic, but its just to give me more general background so I don't keep having to ask so many questions.

Offline gens

  • Jr. Member
  • *
  • Posts: 11
Re: Difference between "Windows native" and "System V" x64 ABIs
« Reply #5 on: August 30, 2012, 01:44:20 AM »
i dont see what is not cleared about the system v calling convention in the abi.pdf
it is a little tehnical, but its all there:

first you classify what your passing
args go in RCX, RDX, R8, R9
if they are floats they go into xmm registers and if floats are returned they are returned there
MEMORY types are passed thru the stack(basicaly anything too big to fit into a register)
things are returned in rax
and syscalls now use "syscall" instead of "int somehex"

theres a bit more in the A.2.1 part of the abi.pdf

oh and linux 32bit and amd64 syscalls have different arguments

here's an example of a triangle i had problems with and asked here http://forum.nasm.us/index.php?topic=1454.0

also heres some general code for filehandling under linux

;open
   mov   rdx, 600o
   mov   rsi, 0
   lea   rdi, [file]
   mov   rax, 2
   syscall

   mov   [fd], rax

you get the file descriptor in rax

;read8
   mov   rdx, 8
   mov   rsi, buff
   mov   rdi, [fd]
   mov   rax, 0
   syscall

buff is where to write sayd read thing

;print8 to stdout
   mov   rdx, 8
   mov   rsi, buff
   mov   rdi, 1
   mov   rax, 1
   syscall


hope this helps a little, im still learning asm so...
i have some linux syscalls in some link somewhere (i think:)) if you need

funny thing is i have to learn to use the stack now because of strtod()

Offline gens

  • Jr. Member
  • *
  • Posts: 11
Re: Difference between "Windows native" and "System V" x64 ABIs
« Reply #6 on: August 30, 2012, 01:56:23 AM »
oh, forgot to say(but is in the examples) syscalls use rax as the first arg
and since i cant edit...

also some links i found while scouring

on syscalls
http://rayseyfarth.com/asm/pdf/ch12-system-calls.pdf

on x64 asm
http://software.intel.com/en-us/articles/introduction-to-x64-assembly/

idk why i didnt read this yet
http://www.osronline.com/ddkx/kmarch/64bitamd_7qqv.htm

and some syscall numbers
http://www.acsu.buffalo.edu/~charngda/linux_syscalls_64bit.html

and some more of the same syscall numbers(from the kernel source)
http://os1a.cs.columbia.edu/lxr/source/arch/x86/include/asm/unistd_64.h