我正在根据 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 eax
、ebx
、ecx
、edx
我不能在不同的 cpuid
执行中使用它们。如 AMD64 SysV ABI
中所述:
r10 temporary register, used for passing a function’s
static chain pointer
r11 temporary register
只有一个严格的临时寄存器r11
,r10
似乎有不同的用途(而且它作为循环计数器的用途不是一个,我显然没有通过任何静态链指针)。
问题: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/