PICレジスタ(%のEBX)とは何をするのでしょうか?
-
09-09-2019 - |
質問
私は前後に1つのスタックフレームから別のジャンプC ++での「危険な」プログラムを書かれています。目標は、呼び出し側にコールスタックの最下位レベルからジャンプする何かをして、再度ダウンバックジャンプし、各時間がその間のすべての呼び出しをスキップすることがある。
私は手動でスタック・ベース・アドレス(設定%ebp
)を変更し、ラベルのアドレスにジャンプすることにより、これを行います。それは完全にまったくスタック破損せずに、gccとICCの両方で、動作します。これは働いていた日は涼しい日だった。
今、私が同じプログラムを取っているし、再書き込み、それをCに、そしてそれは動作しません。具体的には、GCCのV4.0.1(Mac OS)を動作しません。私は(正しく設定され、スタックベースポインタ付き)新しいスタックフレームにジャンプしたら、次の手順では、呼び出しがfprintf
する直前にされて、実行されます。ここに記載された最後の命令は、NULLをデリファレンス、クラッシュします:
lea 0x18b8(%ebx), %eax
mov (%eax), %eax
mov (%eax), %eax
私はいくつかのデバッグを行ってきた、と私は、私は(私が最初の場所で機能を離れる前に観測された値を使用して)スタックフレームを切り替える際に手動で%ebx
レジスタを設定することにより、私はバグを修正することを考え出しました。私は、これはGCCの「位置独立コード」と取引を登録することを読みました。
の位置独立コードとは何ですか?どのように位置独立コードの動作しますか?このレジスタのポインティングされるものに?の
解決
PICは、それがロードされるときに動的に再配置されたコードです。非PICであるコードは、リンク時に設定し、ジャンプやコールのアドレスを持っています。 PICはかなりの.dllのように、このような値が存在するすべての場所を参照するテーブルを持っています。
画像がロードされると、、ローダは、動的にこれらの値を更新します。他の方式は、「ベース」を定義し、ターゲットアドレスがベースに計算を実行することによって決定されたデータ値を参照します。ベースは通常、再びローダによって設定されます。
最後に、他の方式は、既知の相対オフセットに呼び出す様々なトランポリンを使用します。相対オフセットは、ローダによって更新されたコードおよび/またはデータが含まれています。
の異なる方式が選択されている理由はさまざまな理由があります。いくつかは、実行時に高速ですが、ロード遅くなります。いくつかは、ロードする高速ですが、あまり実行時のパフォーマンスを持っています。
他のヒント
グローバルオフセットテーブルにEBX
ポイント。上のPICについてこのリファレンスを参照してください。 I386 に。リンクは、PICはEBX
が使用されている方法であるかを説明ます。