Page 1 of 1

64Bit inline Assembly

Posted: Fri Mar 21, 2008 4:04 am
by Krox
I'm working on my OS for quite a while now, recently I finished nice Ring3 Multitasking on pure AMD64 written in D :D . Now I need some Syscalls, for which I'm using those SYSCALL/SYSRET instructions... thats working, but now I have a problem with inline assembly.

The following code wont work:

Code: Select all

ulong Syscall(ulong id, ulong a, ulong b, ulong c, ulong d)
{
	ulong rv;
	asm
	{
		"syscall" : "=a" rv : "a" ID "D" a "S" b "d" c "r10" d;
	}
	return rv;
}
I works without the last parameter, and I think, gcc doesnt understand the register-name "r10". So, does anyone now the right name for those r8-15 registers? I couldnt find them in the docs...

Posted: Fri Mar 21, 2008 4:36 am
by bluecode
To my knowledge it is only possible to do the following (taken from my OS):

Code: Select all

register uint64_t __return4 asm("r8");
asm volatile("syscall":
                  "=a" (return0), "=D" (return1), "=S" (return2), "=d" (return3), "=r" (__return4):
                  "a" (number), "D" (param0):
                  "rcx", "r11");
return4 = __return4

Posted: Fri Mar 21, 2008 9:18 am
by Krox
Its a pitty, that GCC has such a limitation... even more cause D hasnt got the "register" keyword. So now I'm very limited in the number of parameters, but probably it will be enough anyway. If someone is interested, thats my solution, with the maximum of parameters (yes, the syntax is correct, it slightly differs of C's one)
asm
{
"syscall" :
"=a" return0, "=d" return1 :
"a" id, "D" param0, "S" param1, "d" param2, "b" param3 :
"rcx", "r11";
}
Thanks for your help anyway, nice to see people from lowlevel here :)

Posted: Thu Mar 27, 2008 1:17 am
by piranha
Well, the was I do my syscalls is:

Code: Select all

asm("int $0x80":"=S"(r):"a"(no), "b"(a1), "c"(a2), "d"(a3));
works fine for my purposes.

-JL

Posted: Sat Mar 29, 2008 6:26 am
by Krox
that works with interrupts, but when using the syscall-instruction, RCX is already used for the return-address (stack dont get touched). So even if you store 2 more parameters in EDI and ESI, you are limited to 1 call-id + 4 parameters (rdi, rsi, edx, ebx). I would like to get more, and from the architecture point of view it should be perfectly fine to use the longmode registers r8-r15. The Problem here is GCC, where you cannot specify one specific register of them.

rax = "a", rbx ="b", rdi = "D", rsi="S", etc... but r8-15=???

Posted: Sat Mar 29, 2008 9:38 am
by bluecode
Yea exactly, I hit the same wall. I only know the above workaround.