2

我正在cpuid根据 AMD64 SysV ABI 实现一个在汇编中使用的函数。我需要在函数本身中使用 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

由于cpuidclobbers eax, ebx, ecx,edx我不能在不同的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 兼容?

4

1 回答 1

3

在您确定了用于参数的所有寄存器之后,在这种情况下没有,您只需要关心寄存器是否是易失性的(不会在调用中保留)。

总之,看图3.4的最后一列(for的用法r10从哪里来):没有保留,不用恢复就可以使用。
使用仅告诉您在哪里查找参数(如果需要)以及将返回值放在哪里。
如果您没有在输入中使用静态链指针,您可以r10根据需要尽快覆盖。

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

以供参考:

本小节讨论每个寄存器的用法。寄存器 %rbp、%rbx 和 %r12 到 %r15 “属于”调用函数,并且被调用函数需要保留它们的值。换句话说,被调用函数必须为其调用者保留这些寄存器的值。剩余的寄存器“属于”被调用的函数。5 如果调用函数想要在函数调用中保留这样的寄存器值,它必须将该值保存在其本地堆栈帧中。

于 2019-09-13T07:12:05.820 回答