www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling convention for ASM on Linux AMD64

reply Sean O'Connor <sean.c4s.vn gmail.com> writes:
What calling convention is used for assembly language in Linux 
AMD64?
Normally the parameters go in fixed order into designated 
registers.

import std.stdio;
// Linux AMD64
float* test(float *x,ulong y){
	asm{
		naked;
		align 16;
		mov RAX,RDI;
		ret;
	}
}

void main(){
	float[] f=new float[16];
	writeln(&f[0]);
	float* a=test(&f[0],7);
	writeln(a);
}

If the ulong y parameter is removed from the function definition 
the pointer x goes into RDI as expected.  When y is added it all 
goes wrong. According to AMD64 the pointer should stay in RDI and 
the ulong go into RSI.
Aug 17 2018
parent reply Eugene Wissner <belka caraus.de> writes:
On Saturday, 18 August 2018 at 04:16:11 UTC, Sean O'Connor wrote:
 What calling convention is used for assembly language in Linux 
 AMD64?
 Normally the parameters go in fixed order into designated 
 registers.

 import std.stdio;
 // Linux AMD64
 float* test(float *x,ulong y){
 	asm{
 		naked;
 		align 16;
 		mov RAX,RDI;
 		ret;
 	}
 }

 void main(){
 	float[] f=new float[16];
 	writeln(&f[0]);
 	float* a=test(&f[0],7);
 	writeln(a);
 }

 If the ulong y parameter is removed from the function 
 definition the pointer x goes into RDI as expected.  When y is 
 added it all goes wrong. According to AMD64 the pointer should 
 stay in RDI and the ulong go into RSI.
If you compile with DMD, DMD passes the arguments in reverse order. LDC and GDC use normal C calling conventions.
Aug 17 2018
parent reply Eugene Wissner <belka caraus.de> writes:
On Saturday, 18 August 2018 at 06:47:36 UTC, Eugene Wissner wrote:
 On Saturday, 18 August 2018 at 04:16:11 UTC, Sean O'Connor 
 wrote:
 What calling convention is used for assembly language in Linux 
 AMD64?
 Normally the parameters go in fixed order into designated 
 registers.

 import std.stdio;
 // Linux AMD64
 float* test(float *x,ulong y){
 	asm{
 		naked;
 		align 16;
 		mov RAX,RDI;
 		ret;
 	}
 }

 void main(){
 	float[] f=new float[16];
 	writeln(&f[0]);
 	float* a=test(&f[0],7);
 	writeln(a);
 }

 If the ulong y parameter is removed from the function 
 definition the pointer x goes into RDI as expected.  When y is 
 added it all goes wrong. According to AMD64 the pointer should 
 stay in RDI and the ulong go into RSI.
If you compile with DMD, DMD passes the arguments in reverse order. LDC and GDC use normal C calling conventions.
You can define test() as exter(C) to force dmd to use the expected arguments order.
Aug 17 2018
parent Sean O'Connor <sean.c4s.vn gmail.com> writes:
Okay, cool, thanks for the information.  The main reason for 
using D versus Java for me at the moment is that array slices 
allow me avoid lots of intermediate buffers that Java is forcing 
me to use.
Also the line count is about 2/3 of Java. Further I can directly 
embed any assembly language I need, rather than using JNI.
Maybe some day a version of D for graal can be written, though 
you would lose native assembly language.
https://github.com/oracle/graal
All I really want though is a sane low level programming language 
or a sane version of C.
Aug 18 2018