2016-03-18 7 views
3

最新のOSでは、メモリアドレスバインディングが「動的」で、実行時に発生することがあります。しかし、我々は仮想メモリスキームを使用し、各プロセスは独自の仮想ユーザメモリ空間を取得するので、なぜ我々はまだ遅く、実行時バインディングをしますか?仮想ページアドレスが物理ページにマップされるため、コンパイル時アドレスバインディングを実行できませんか?ランタイムメモリアドレスバインディングの必要性

答えて

4

実行可能ファイル自体が固定仮想アドレスにマップされる可能性のある、ほとんどのOSで実行可能ファイルのリンク時バインディングを使用します。実行時に再配置を必要とせずに、場所のいたるところに絶対アドレスを埋め込むことができます。もちろん、異なるプロセスで同じ仮想アドレスを使用できるためです。仮想メモリのないシステムでは、各プロセスが異なるアドレスを使用する必要があります。

これはライブラリには当てはまりません。ライブラリは、ロードしようとするプロセスで空きになるアドレスの範囲を知ることができないため、position-independent codeを使用する必要があります。

OS Xでも実行可能ファイルにはPICが必要です。私はなぜそれを見上げたことはありません。多分彼らはASLRをやりたいと思っています。

私は完全に間違っているかもしれませんが、私はWin9xが位置に依存しないコードを必要としないことを覚えていると思うし、DLLをインストールすることは、

4

仮想メモリと動的バインディングは、2つの独立した概念です。動的バインディングは仮想メモリのないシステムで行われます。

ほとんどの場合、アプリケーションは位置独立コードを使用しようとします。これは、メモリ内のどこにでもロードされ、正しく実行されるコードです。コンパイラは、オフセットを使用して位置独立コードを生成します。多くのプロセッサは、プログラムカウンタ/命令ポインタレジスタからの相対的なアドレス指定がメモリ位置にアクセスすることを可能にする。

あなたのようなグローバル変数持つことができます。

int x ; 

をして

main() 
{ 
    int y = x + 1 ; 
} 

コンパイラとリンカユーザが、相対的なプログラムがメモリ内の任意の場所に配置することができますそれに対処することができ、それを参照します。リンク時に相対アドレスを使用してこの問題を引き起こすような

もの:

static int *x = &y ; 

あなたのリンカはここに2つの選択肢があります。 Etherはyが固定位置にあることを強制することができ(コードは位置に依存しないことを意味する)、実行時に解決されるアドレスフィックスアップ(通常行われるもの)を含むことができます。後者の場合、プログラムローダーは実行ファイルからフィックスアップを読み取り、読み込まれたときにその変数をアドレスに初期化します。

他のフィックスアップは、共有ライブラリ(別名DLL)を使用している場合に発生します。共有ライブラリは、リンクされているすべてのプログラムを再リンクする必要なく、更新することができます。共有ライブラリにはユニバーサルシンボルのテーブルがあります(つまり、ライブラリ関数の名前など、ライブラリの外側に表示されるシンボル)。ライブラリにコードを追加すると、状況が変わります。

共有ライブラリにリンクすると、実行可能ファイルは共有ライブラリ(通常は関数)内のグローバルへの動的マッピングを定義します。実行時に、ローダーは実行可能ファイル内のこの情報を使用して、参照されている関数のアドレスを検索し、共有ライブラリをロードする場所と一致するようにアドレスを修正します。

関連する問題