这是寄存器加载代码的列表:
a eax
b ebx
c ecx
d edx
S esi
D edi
I 常量值(0 到 31)
q,r 动态分配的寄存器(见下文)
g eax、ebx、ecx、edx 或内存中的变量
A eax 和 edx 组合成一个 64 -bit 整数(使用 long long)
但这是英特尔 i386 的寄存器限制。我的问题是在哪里可以找到 intel x86_64 系统的寄存器约束,例如:
? %r10
? %r8
? %rdx
等等。
这是寄存器加载代码的列表:
a eax
b ebx
c ecx
d edx
S esi
D edi
I 常量值(0 到 31)
q,r 动态分配的寄存器(见下文)
g eax、ebx、ecx、edx 或内存中的变量
A eax 和 edx 组合成一个 64 -bit 整数(使用 long long)
但这是英特尔 i386 的寄存器限制。我的问题是在哪里可以找到 intel x86_64 系统的寄存器约束,例如:
? %r10
? %r8
? %rdx
等等。
GCC 没有为 , 之类的寄存器提供这样的r10
约束r8
。但是,您可以使用名为Local Register Variables的功能。请在使用此功能之前仔细阅读文档,尤其是警告段落。
例如:
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;
}
另请参见musl 的系统调用存根实现。
机器特定的约束在gcc 手册中有一个部分- 丑陋的细节可以在config/i386/constraints.md中找到。
一些约束对于 x86-64 有不同的含义,例如q
is %eax
, %ebx
, %ecx
, %edx
in 32-bit mode;在 64 位模式下,它是任何通用整数寄存器 - 基本上与r
约束相同。特定的寄存器名称,例如a
now 指代%rax
、d
to%rdx
等。
%r8
但是,对于...没有特殊的限制或名称%r15
。这里有一个关于内联汇编和约束使用的优秀(x86-64 特定)教程。