一部の関数では、元のスタックが変更されないようにスタックを切り替える必要があります。そのために、以下のように2つのマクロを作成しました。
#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が使用されている場合)が適用されている場合、これが正しいかどうかもわかりません。このアプローチに問題や副作用がありますか?