如何在GCC内联汇编中指定Intel x86_64寄存器r8到r15的寄存器约束?

21
这里是寄存器加载代码列表:

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位整数(使用long longs)

但是这是针对intel i386的寄存器约束条件。我的问题是在哪里可以找到intel x86_64系统的寄存器约束条件,例如:

? %r10
? %r8
? %rdx

等等。
2个回答

18

GCC不像r10r8这样的寄存器提供此类约束条件。但是,您可以利用一个叫做局部寄存器变量的特性。在使用此功能之前,请仔细阅读文档,特别是警告段落。

例如:

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实现的系统调用存根


13
机器特定的约束条件在gcc手册中有一个部分 - 详细信息可以在config/i386/constraints.md中找到。

一些约束对于x86-64有不同的含义,例如,在32位模式下q%eax%ebx%ecx%edx;在64位模式下,它是任何通用整数寄存器,基本上与r约束相同。特定寄存器名称如a现在指的是%raxd%rdx,等等。

然而,对于%r8..%r15,没有特殊的约束或名称。这里有一个优秀的(x86-64特定的)内联汇编和约束使用教程here


非常感谢。我在谷歌上搜索了很长时间,但什么都没有找到。我甚至找不到任何指出它不存在的东西。 - Jin Chen
我已经对你的回答进行了负评,因为它实际上没有回答 OP 的问题,而是将答案推迟到外部资源。Stack Overflow 的答案必须是自包含的。请扩展你的答案,涵盖你链接的相关部分。 - fuz
1
你至少可以提一下,使用register ... asm本地变量是强制"r"选择你想要的寄存器的方法,就像其他答案所展示的那样。在某些非x86 ISA上,这也是你所做的事情,因为通常没有特定的寄存器约束条件。 - Peter Cordes
@BrettHale 与Peter所说的一样。只要你的回答实际上没有解释如何实现OP想要的,我的反对票就会保留。 - fuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接