How to specify register constraints on the Intel x86_64 register r8 to r15 in GCC inline assembly?
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.
The machine specific constraints have a section in the gcc manual - the ugly details are found in config/i386/constraints.md.
Some constraints have different meanings for x86-64, e.g., q
is %eax
,%ebx
,%ecx
,%edx
in 32-bit mode; in 64-bit mode, it's any general purpose integer register - and essentially the same as the r
constraint. Specific registers names like a
now refer to %rax
, d
to %rdx
, etc.
There are, however, no special constraints or names for %r8
.. %r15
. There's an excellent (x86-64 specific) tutorial on inline assembly and constraint use here.