【问题标题】:How to specify register constraints on the Intel x86_64 register r8 to r15 in GCC inline assembly?如何在 GCC 内联汇编中指定 Intel x86_64 寄存器 r8 到 r15 的寄存器约束?
【发布时间】:2013-06-14 02:48:38
【问题描述】:

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

一个eax
b ebx
c ecx
d edx
西西
编辑
I 常数值(0 到 31)
q,r 动态分配的寄存器(见下文)
g eax、ebx、ecx、edx 或内存中的变量
一个 eax 和 edx 组合成一个 64 位整数(使用 long longs)

但这是英特尔 i386 的寄存器限制。我的问题是在哪里可以找到 intel x86_64 系统的寄存器约束,例如:

? %r10
? %r8
? %rdx

等等。

【问题讨论】:

    标签: assembly gcc x86-64 inline-assembly cpu-registers


    【解决方案1】:

    机器特定的约束在gcc manual 中有一个部分 - 丑陋的细节在config/i386/constraints.md 中找到。

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

    但是,%r8 .. %r15 没有特殊限制或名称。有一个关于内联汇编和约束使用的优秀(x86-64 特定)教程here

    【讨论】:

    • 非常感谢。我谷歌了很长时间,但什么也没得到。我什至找不到指出它不存在的东西。
    • 我对您的答案投了反对票,因为它实际上并没有回答 OP 的问题,而是将答案推迟到外部资源。堆栈溢出答案必须是自包含的。请扩展您的答案以涵盖您链接的资源的相关部分。
    • 您至少可以提到register ... asm 局部变量是强制"r" 选择您想要的寄存器的方法,就像其他答案所示。这也是您在一些通常没有任何特定寄存器约束的非 x86 ISA 上所做的事情。
    • @BrettHale 彼得说了什么。只要您的回答实际上并未解释如何实现 OP 想要的,我的反对意见就会保留。
    【解决方案2】:

    GCC 不为r10r8 等寄存器提供此类约束。但是,您可以使用名为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's implementation of syscall stubs

    【讨论】:

      猜你喜欢
      • 2013-04-06
      • 2012-08-26
      • 2021-05-20
      • 2015-11-01
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      相关资源
      最近更新 更多