19
votes

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.

2

2 Answers

12
votes

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.

17
votes

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.