将函数标记为脏(指定调用者应保存所有寄存器)

use*_*108 3 c c++ gcc

我有一个函数f()可以销毁函数调用过程中的所有寄存器(堆栈指针除外)。我怎样才能将其传达给gcc,以便调用者在调用之前保存它想要保存的所有寄存器f()

编辑:我正在编写一个协程处理程序,它需要在切换到另一个协程之前保存状态,并且我想保存尽可能小的状态。假设我们有一个函数yield(),标记为“脏”,它会破坏除堆栈指针之外的所有内容。在控制权返回到我们的协程之后,该函数将神奇地返回,但最好是调用者而不是被调用者(因为调用者最清楚需要保存哪些寄存器)在调用之前保存需要保存的所有寄存器,然后yield()恢复它们然后。

Avi*_*Avi 5

这个想法违反了最小惊讶原则,因此应该避免。

作为调用者,我不希望在调用函数时担心寄存器内容。此外,如果您希望调用者处理它,为什么不在 f() 内部处理它呢?不仅调用者不需要知道,而且您只需要一种实现。根据您的建议,每个调用者都需要处理保存/恢复上下文,这可能很容易出错。

基本解决方案可以使用RAII在 f() 中处理此问题。就像是:

class ContextGuard {
  public:
    // Stores the current context
    ContextGuard() { ... }
    // Restores the current context
    ~ContextGuard() { ... }
  private:
     ...
};

...

void f() {
   ContextGuard contextGuard; // Saves the current context
   ... // Do stuff that mucks with the registers
} <-- contextGuard is destroyed here and the context is restored.
Run Code Online (Sandbox Code Playgroud)

如何处理存储/恢复上下文是另一回事。Boost.Context可能会为您提供您所需要的。

最后一点,除了堆栈指针之外,还有一些与寄存器有关的其他复杂问题。您需要在这里考虑特定于平台的函数调用约定,可能还有其他因素。如果您以认为需要恢复寄存器的方式处理寄存器,那么您将必须真正理解您打算运行此代码的所有平台的复杂性。