実験用に自分のスタックを一時的に使用するコードを書いています。これは、リテラルのインラインアセンブリを使用したときに機能しました。私はebpのオフセットとして可変ロケーションをハードコーディングしていました。しかし、私は自分のコードがメモリアドレスをハードコードすることなく動作することを望んでいたので、GCCのEXTENDED INLINE ASSEMBLYを調べました。私が持っているものは、次のとおりです。
volatile intptr_t new_stack_ptr = (intptr_t) MY_STACK_POINTER;
volatile intptr_t old_stack_ptr = 0;
asm __volatile__("movl %%esp, %0\n\t"
"movl %1, %%esp"
: "=r"(old_stack_ptr) /* output */
: "r"(new_stack_ptr) /* input */
);
これは、まずスタックポインタを変数old_stack_ptrに保存することです。次に、スタックポインタ(%esp)がnew_stack_ptrに保存したアドレスで上書きされます。
これにもかかわらず、GCCは%espをold_stack_ptrに保存していましたが、%espをnew_stack_ptrに置き換えていませんでした。より深い検査の際に、私はそれが実際に私のアセンブリを拡大し、それは以下の通りです自身の指示、です追加が見つかりました:
mov -0x14(%ebp),%eax
mov %esp,%eax
mov %eax,%esp
mov %eax,-0x18(%ebp)
私はそれが明示的として宣言されていないため、GCCは、ESP%を維持しようとしていると思います"出力"オペランド...私はこれで完全に間違っている可能性があります...
私は実際には、これを行うために拡張インラインアセンブリを使用したいと思います。 %ebpのアセンブリへのオフセット、そして私はむしろこれのような変数名を使うでしょう...特に、このコードはいくつかの異なるシステムで動作する必要があります。私は明白にすることができます変数の位置を言うと...しかし、私はそれが余分なものをやっている理由を理解していないと私は拡張アセンブリを使用して以来、それはこれをやって以来、それは以前のようにスタックポインタを上書きしないようにしていません。
何か助けていただきありがとうございます!
これが役立つかどうかわかりませんが、 '-fomit-frame-pointer'(' -O1'以上で有効)は '%ebp'を心配する必要がなくなります。 – DaoWen
デバッグ(最適化なし)ビルドを行っているため、GCCはデフォルトで潜在的なエラーをキャッチするため、余分なものはおそらく存在します。 "GCC Stack Frame Checks"を検索して、GCCが提供するオプションを確認してください。 – Skizz