digitalmars.D - X86-64 calling conventions
- rumbu (48/48) Dec 06 2016 I know already that the D calling convention x86-64 is not the
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.
Dec 06 2016