リンクアドレスはプログラムの実行が行われるアドレスであり、ロードアドレスはプログラムが実際に配置されるメモリ内のアドレスです。
今、私は混乱しています プログラムカウンターの値は何ですか? それはロードアドレスですか、それともリンクアドレスですか?
リンクアドレスはプログラムの実行が行われるアドレスであり、ロードアドレスはプログラムが実際に配置されるメモリ内のアドレスです。
今、私は混乱しています プログラムカウンターの値は何ですか? それはロードアドレスですか、それともリンクアドレスですか?
どちらも異なる概念であり、異なるコンテキストで使用されます。リンカー/ローダーは、主にコードの再配置と変更を担当します。PC は、プログラム シーケンスの位置を示すデジタル カウンターです (リンカー/ローダーのような型のアドレス/場所ではありません)。
リンクと読み込み:-
リンカーまたはローダーのアクションの核心は、再配置とコードの変更です。コンパイラまたはアセンブラがオブジェクト ファイルを生成するとき、ファイル内で定義されたコードとデータの再配置されていないアドレスを使用してコードを生成し、通常、別の場所で定義されたコードとデータにはゼロを使用します。リンク プロセスの一部として、リンカは割り当てられた実際のアドレスを反映するようにオブジェクト コードを変更します。たとえば、eax レジスタを使用して変数 a の内容を変数 b に移動する x86 コードのこのスニペットについて考えてみます。
mov a,%eax mov %eax,b
a が同じファイルの 1234 hex の位置で定義され、b が別の場所からインポートされた場合、生成されるオブジェクト コードは次のようになります。
A1 34 12 00 00 mov a,%eax A3 00 00 00 00 mov %eax,b
各命令には、1 バイトのオペコードとそれに続く 4 バイトのアドレスが含まれます。最初の命令は 1234 への参照を持ち (x86 は右から左へのバイト順を使用するため、バイトが逆になります)、2 番目の命令は b の位置が不明なためゼロへの参照を持ちます。
ここで、a が配置されているセクションが 16 進数で 10000 バイト移動し、b が 16 進数で 9A12 になるように、リンカがこのコードをリンクするとします。リンカーはコードを次のように変更します。
A1 34 12 01 00 mov a,%eax A3 12 9A 00 00 mov %eax,b
つまり、最初の命令のアドレスに 10000 を追加するので、a の再配置されたアドレス 11234 を参照し、b のアドレスにパッチを当てます。これらの調整は命令に影響しますが、オブジェクト ファイルのデータ部分のポインターも同様に調整する必要があります。
プログラム カウンター (PC) は、コンピューターがプログラム シーケンスのどこにあるかを示すプロセッサ レジスタです。
典型的な中央処理装置 (CPU) では、PC はデジタル カウンター (「プログラム カウンター」という用語の由来) であり、CPU ハードウェア内の多くのレジスタの 1 つです。命令サイクルはフェッチで始まります。フェッチでは、CPU が PC の値をアドレス バスに配置してメモリに送信します。
メモリは、データ バス上のそのメモリ位置の内容を送信することによって応答します。(これは、実行可能な命令がメモリ内の通常のデータと一緒に格納され、同じように処理されるストアド プログラム コンピューター モデルです)。
フェッチに続いて、CPU は実行に進み、取得したメモリの内容に基づいて何らかのアクションを実行します。このサイクルのある時点で、次に実行される命令が別の命令になるように PC が変更されます (通常、現在の命令の最後のメモリ位置の直後のメモリ アドレスから始まる命令がインクリメントされます)。 .
「ロードアドレス」という用語をあなたの考えから外します。これは、最新のオペレーティング システムには実際には存在しません。同じアドレス空間にロードされた複数のプログラム (およびメモリの連続した領域にロードされた各プログラム) の昔は、ロード アドレスが重要でした。今はそうではありません。彼が理由です。
実行可能ファイルは通常、多数の異なるプログラム セグメントを定義します。これらはメモリに連続してロードされない場合があります。たとえば、リンカーは、多くの場合、プログラムの他の領域から離れたスタック領域の作成を指示します。
実行可能ファイルは、PC の初期値であるべき場所を示します。これは、最初のプログラム セグメントは言うまでもなく、プログラム セグメントの開始点ではない可能性があります。