linux - 编写 AMD64 SysV 程序集时使用哪些寄存器作为临时寄存器?

标签 linux assembly x86 x86-64 abi

我正在根据 AMD64 SysV ABI 在汇编中使用 cpuid 实现一个函数。我需要在函数本身中使用 2 个临时寄存器:第一个用于累积返回值,第二个用作计数器。

我的函数当前如下所示:

;zero argument function
some_cpuid_fun:
  push rbx

  xor r10d, r10d ;counter initial value
  xor r11d, r11d ;return value accumulator initial value
  some_cpuid_fun_loop:
  ;...
  cpuid
  ;update r10d and r11d according to the result


  mov eax, r11d
  pop rbx
  ret

由于 cpuid clobbers eaxebxecxedx 我不能在不同的 cpuid 执行中使用它们。如 AMD64 SysV ABI 中所述:

r10    temporary register, used for passing a function’s
       static chain pointer

r11    temporary register

只有一个严格的临时寄存器r11r10似乎有不同的用途(而且它作为循环计数器的用途不是一个,我显然没有通过任何静态链指针)。

问题:some_cpuid_fun 函数实现 AMD64 SysV ABI 兼容吗?如果没有,如何重写它以保持与 ABI 兼容?

最佳答案

在您确定了用于参数的所有寄存器(在本例中没有)之后,您只需关心寄存器是否是 volatile 的(在调用之间不保留)。

简而言之,看看图 3.4 的最后一列(其中 r10 的用法来自于此):它保留,因此您可以在不使用它的情况下使用它恢复它。
用法列仅告诉您如果需要的话在哪里查找参数以及在哪里放置返回值。
如果您不在输入中采用静态链指针,则可以根据需要立即覆盖 r10

所以,是的,使用 r10 作为临时寄存器是 ABI 兼容的。

供引用:

This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling function and the called function is required to preserve their values. In other words, a called function must preserve these registers’ values for its caller. Remaining registers “belong” to the called function. 5 If a calling function wants to preserve such a register value across a function call, it must save the value in its local stack frame.

关于linux - 编写 AMD64 SysV 程序集时使用哪些寄存器作为临时寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57917552/

相关文章:

汇编语言乘法问题

c - 汇编,对sum负值处理

linux - 共享内存和进程信号量 (IPC)

mysql - 无法从终端设置外键检查 =0

assembly - ds, es 寄存器

assembly - 在运行时检测 64 位模式的 x86-32/x86-64 多语言机器代码片段?

linux - gdb 无法打开共享对象文件

c - 串口通讯中换行字符的意义

c - 为什么一项任务比另一项任务快?

c++ - 原子商店。结构