【问题标题】:Assembly push or reserve stack for 2 or more registers用于 2 个或更多寄存器的汇编推送或保留堆栈
【发布时间】: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


【解决方案1】:

从 Pentium-M 开始,x86 CPU 有一个堆栈引擎来处理 RSP 更新,使得 push/pop 像 mov store/load 一样是单微指令。这就是 GCC 使用 push/pop 的原因,除非您使用 -mtune=pentium3 或其他东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 2016-03-15
    • 2014-08-04
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2016-01-24
    相关资源
    最近更新 更多