对于某些功能,我需要切换堆栈以使原始堆栈保持不变。为此,我编写了两个宏,如下所示。
#define SAVE_STACK() __asm__ __volatile__ ( "mov %%rsp, %0; mov %1, %%rsp" : \
"=m" (saved_sp) : "m" (temp_sp) );
#define RESTORE_STACK() __asm__ __volatile__ ( "mov %0, %%rsp" : \
"=m" (saved_sp) );
这里temp_sp和saved_sp是线程局部变量。temp_sp指向我们使用的临时堆栈。对于我想要不修改其原始堆栈的函数,我将 SAVE_STACK 放在开头,将 RESTORE_STACK 放在底部。例如,像这样。
int some_func(int param1, int param2)
{
int a, b, r;
SAVE_STACK();
// Function Body here
.....................
RESTORE_STACK();
return r;
}
现在我的问题是这种方法是否可行。在 x86(64 位)上,通过rbp寄存器访问局部变量和参数,并在函数序言中相应地减去rsp,直到在函数尾声中添加它以使其恢复到原始值时才被触及。因此,我认为这里没有问题。
我不确定,如果这在上下文切换和信号存在的情况下是正确的。(在 Linux 上)。此外,如果函数是内联的,或者是否应用了尾调用优化(使用jmp而不是call ) ,我也不确定这是否正确。你觉得这种方法有什么问题或副作用吗?