inline ASM function calling conventions.
Basile B.
b2.temp at gmx.com
Sun Sep 30 11:53:17 UTC 2018
On Sunday, 30 September 2018 at 10:46:33 UTC, Sjoerd Nijboer
wrote:
> I'm kinda puzzled.
>
> I'm having trouble getting started with inline asm in D.
> Suppowse I have the following:
>
> void Foo(MyStrunct* first_arg, MyStrunct* second_arg)
> {
> asm
> {
> naked;
> version(X86)
> {
> /* Do something with the content of I and J. */
> }
> version(X86_64)
> {
> /* Do something with the content of I and J. *?
> }
> }
> }
>
> void Bar()
> {
> MyStrunct heapStructA, heapStructB;
>
> // do some initialization.
>
> Foo(heapStructA, heapStructB);
> }
>
> Suppose I would like to pass first_arg and second_arg by
> register to `Foo`, what calling convention should I use? I'm
> having trouble identifying the correct calling convention I
> should be using for X86 and X86_64 in D.
>
> I've tried a couple using https://godbolt.org/ and DMD
> parameters '-g -m32', but I can't seem to find any that will
> pass by register. Is there one? Will it also work for LDC and
> GDC?
Hello, i think this should be here
(https://dlang.org/spec/abi.html) because myself i never remember
them correctly without playing a bit with a disassembler.
After playing a bit:
Linux x86_64:
extern(D) void Foo(MyStruct* s1, MyStruct* s2, MyStruct* s3,
MyStruct* s4)
{
asm
{
naked;
// rcx -> s1
// rdx -> s2
// rsi -> s3
// rdi -> s4
ret;
}
}
====================
Linux x86 / Window x86:
extern(D) void Foo(MyStruct* s1, MyStruct* s2, MyStruct* s3,
MyStruct* s4)
{
asm
{
naked;
// ebx -> s1
// edx -> s2
// ecx -> s3
// eax -> s4
ret;
}
}
====================
Win64 has a different calling convention than Linux64, i cant
remember the difference.
====================
Linux x86_64 example:
module runnable;
import std.stdio;
alias writeInt = writeln!int;
struct MyStruct{int i;}
extern(D) void foo(MyStruct* s1, MyStruct* s2, MyStruct* s3,
MyStruct* s4)
{
asm
{
naked;
mov RAX, RDI; // move s4 here since we call
something...
push RDX; // save s2
push RSI; // save s3
push RAX; // save s4
mov RDI, MyStruct.i.offsetof[RCX];
call writeInt;
pop RAX; // restore...
pop RSI;
pop RDX;
push RSI; // save s3
push RAX; // save s4
mov RDI, MyStruct.i.offsetof[RDX];
call writeInt;
pop RAX; // restore
pop RSI;
push RAX; // save s4
mov RDI, MyStruct.i.offsetof[RSI];
call writeInt;
pop RAX; // restore
mov RDI, MyStruct.i.offsetof[RAX];
call writeInt;
ret;
}
}
void main()
{
MyStruct s1 = MyStruct(1);
MyStruct s2 = MyStruct(2);
MyStruct s3 = MyStruct(3);
MyStruct s4 = MyStruct(4);
foo(&s1, &s2, &s3, &s4);
}
here too :
https://run.dlang.io/is/CWd4aO
More information about the Digitalmars-d-learn
mailing list