X86-64 calling conventions
rumbu via Digitalmars-d
digitalmars-d at puremagic.com
Tue Dec 6 11:44:09 PST 2016
I know already that the D calling convention x86-64 is not the
same as the one of the corresponding C compiler (register order
is reversed on Windows and Linux) - details here:
http://forum.dlang.org/post/mailman.1981.1415996395.9932.digitalmars-d@puremagic.com
But even with extern(C), there is something wrong on x86-64 when
passing arrays as parameters.
In x86-32, the D calling convention is clear for arrays (even
that's not documented, credits go to the std.bigint creator - Don
Clungston):
void foo(uint[] x, uint p1, uint p2) will be translated to
push x.ptr;
push x.length;
push p1;
push p2;
call foo;
In a "naked" asm context, it's easy to access parameters
p2 = [ESP + 4]
p1 = [ESP + 8]
x.length = [ESP + 12]
x.ptr = [ESP + 16]
---
Now, on x86-64 (Windows), following the same schema, I expected
something like this:
mov RCX, x.ptr;
mov RDX, x.length;
mov R8, p1;
mov R9, p2;
(standard Windows x86-64 calling convention)
Instead, the compiler generates something very strange:
mov R8, p2 //somehow ok, third parameter (even I expected to be
the fourth)
mov RDX, p1 //somehow ok, second parameter (even I expected to
be the third)
mov [RBP-0x10], x.length //why?
mov [RBP-0x08], x.ptr //why?
lea RCX, [RBP-0x10] //pointer to x.length?
Finally we have:
p2 = R8
p1 = RDX
x.length = [RCX]
x.ptr = ?
Now the questions:
1. Is there any intention to correct the registry reversing
behaviour for extern(D)?
2. Will someone fully document the ABI for x86-32 and x86-64?
3. How do I find in a naked asm context on x86-64 the starting
address of an array passed as parameter?
Thanks.
More information about the Digitalmars-d
mailing list