[ldc, asm] Accessing function parameters in inline assembler
Manuel König
manuelk89 at gmx.net
Fri Oct 1 14:54:36 PDT 2010
Hi,
I'm trying to understand how the inline assembler works in ldc, but I
couldn't find any docs about the calling conventions. When I try to
access the stack parameters, the function always segfaults, and I don't
know how to fix it. I also looked at tango's BigNum asm implementation,
and I tried to do the same (I didn't test though if tango's BigNum
works). My platform is linux x86_64, here's what I did (or was trying
to do):
import tango.io.Stdout;
/*
In the following two functions I try to implement the identity
function that simply returns it's parameter. I don't get it to work,
though. */
uint identity_v1(uint x)
{
asm
{
// D-linkage: x should be in EAX, result is returned in EAX
// shouldn't have to do anything
naked;
ret;
}
}
uint identity_v2(uint x)
{
asm
{
// ok, identity_v1 doesn't work, maybe x is on the stack?
naked;
mov EAX, [ESP+4]; // segfaults, why?
ret;
}
}
// identity_v1/2 don't work, check if the result is really returned in
EAX
uint test(uint x)
{
asm
{
naked;
mov EAX, 123;
ret;
}
}
/* a bit more complex: returns true iff (a*b > c*d) */
bool cmpProduct(long a, long b, long c, long d)
{
// I'm assuming d,c,b,a are in [ESP+i*8] for i=1,..,4
// in that order
asm
{
naked;
// RBX:RCX = a*b
mov RAX, [ESP+4*8];
imul RAX, [ESP+3*8]; // why isn't one operand enough? bug?
mov RBX, RDX;
mov RCX, RAX;
// RDX:RAX = c*d
mov RAX, [ESP+2*8];
imul RAX, [ESP+1*8];
// EAX = (a*b > c*d)
cmp RBX, RDX;
jg AB_GREATER_CD;
jl AB_LESS_CD;
cmp RCX, RAX;
xor EAX, EAX;
setg AL;
ret;
AB_GREATER_CD:
mov EAX, 1;
ret;
AB_LESS_CD:
xor EAX, EAX;
ret;
}
}
void main()
{
Stdout.formatln("identity_v1 = {}", identity_v1(4)); // returns 254, regardless of the parameter
Stdout.formatln("identity_v2 = {}", identity_v2(4)); // segfaults
Stdout.formatln("test = {}", test(4)); // returns 123, as expected
Stdout.formatln("cmpProduct = {}", cmpProduct(1,2,3,4)); // segfaults
}
So my questions are:
(1) how do I access parameters?
(2) what are the ldc calling conventions on x86_64 platforms?
(3) what do I have to do to make identity_v1/2 and cmpProduct work?
(when (1) or (2) are sufficiently answered, question (3) of course
becomes obsolete)
More information about the Digitalmars-d-learn
mailing list