Here's the list of register loading codes:
a eax
b ebx
c ecx
d edx
S esi
D edi
I constant value (0 to 31)
q,r dynamically allocated register (see below)
g eax, ebx, ecx, edx or variable in memory
A eax and edx combined into a 64-bit integer (use long longs)
But this is register constraints for intel i386. My question is where I can find the register constraints of intel x86_64 system, like:
? %r10
? %r8
? %rdx
and so on.
GCC doesn't provide such constraint for registers like r10
, r8
. However, you can make use of a feature called Local Register Variables. Please read the document carefully before using this feature, especially the warning paragraph.
For example:
static inline __attribute__((always_inline))
long syscall4(long n, long a1, long a2, long a3, long a4) {
long ret;
register long r10 __asm__("r10") = a4;
__asm__ __volatile__ (
"syscall\n\t"
: "=a"(ret)
: "a"(n),
"D"(a1),
"S"(a2),
"d"(a3),
"r"(r10)
: "memory",
"rcx",
"r11"
);
return ret;
}
See also musl's implementation of syscall stubs.