【发布时间】:2020-04-12 18:13:51
【问题描述】:
我想在我的函数中使用 'rbx' 和 'rcx' 寄存器,在使用它们之前,我想保存它们。由于它是 2 个寄存器,我想知道哪种方式更好? push 他们一个接一个或 保留堆栈(16 字节)并将每个值复制到堆栈中并...
方式1:
FUNC:
push rbx
push rcx
...
...
pop rbx
pop rcx
方式2:
sub rsp, 16
mov QWORD [rsp], rbx
mov QWORD [rsp+8], rcx
...
...
mov rbx, QWORD [rsp]
mov rcx, QWORD [rsp+8]
add rsp, 16
第二种方式有更多的源代码(大小),但我说的是CYCLE。当我只想使用一个寄存器时,很明显我必须使用push,但是对于这样的 2 个或更多寄存器我应该怎么做呢?将它们一一推送或堆栈保留并...?
听说推送是: 1 - 保留堆栈 2 - 将寄存器值复制到保留堆栈中
还有流行的是: 1 - 将值复制到寄存器中 2 - 恢复堆栈
所以对于 2 个或更多寄存器,我可以自己完成,无需多保留和恢复(堆栈)
【问题讨论】:
-
Gcc 使用推送。我假设那些人已经证实这是最好的方法(或者至少不会更糟)。处理器对更新堆栈指针进行了特殊优化。
-
您熟悉典型的调用约定吗?一般不需要保留rcx。如果你从你自己的汇编函数中调用这个函数,你可以使用任何你想要的约定,但我发现在大多数情况下遵循正常约定会更容易。
标签: assembly x86-64 callstack micro-optimization