内部識別子 (
auto
、ローカル変数、ラベルなど) はリンカーによってリンクされていますか?
(私の現在の知識によると、そうではありません。「私は正しいですか?」と尋ねたいです。)
そして別のこと:
- 「ファイルスコープ以外のすべてのものは、リンカーによってまったくリンクされない」と言うのは正しいですか?
内部識別子 (
auto
、ローカル変数、ラベルなど) はリンカーによってリンクされていますか?
(私の現在の知識によると、そうではありません。「私は正しいですか?」と尋ねたいです。)
そして別のこと:
- 「ファイルスコープ以外のすべてのものは、リンカーによってまったくリンクされない」と言うのは正しいですか?
「組み立てる」の意味によります。リンカー/ローダーは、基本的に次の 3 つのことを行います。
ローカルシンボルで何が起こるかを見ると(自動ではなく、ファイルスコープの「静的」シンボルにとどまります)、コンパイルは次のような情報を提供します
しかし、それが生成するコード内の実際の数値でそのアドレスを参照できますか? いいえ: データ セグメントは、セグメント レジスタからのオフセット (最近ではめったにありませんが、セグメント化されたアドレス空間はほとんどなくなっています) またはベース アドレスからのオフセットのいずれかです。
しかし、コンパイラは、データ セグメント内のどこにストレージが配置されるかを知ることができません。したがって、リンカーがこの情報を提供するのを待つ必要があります。
リンカーは何を提供できますか? オブジェクト ファイルからすべてのデータ セグメント定義を追加して収集するため、完全な静的データ セグメントを認識し、その結果、データ セグメントを指すシンボルのオフセットを認識します。しかし、絶対アドレスでパッチできますか? それはオペレーティング システムによって異なります。固定データ セグメント ベース アドレスの規則がある場合、リンカはこの段階ですでにアドレスを認識しています。
しかし、そのアドレスを提供することがオペレーティング システムの構成とプロセスの読み込みの一部である場合、リンカはデータ セグメントへのオフセットにのみパッチを適用できます (つまり、「foobar という名前の 4 バイトが必要です」へのシンボリック参照は「foobar は NNN になります」になります)。バイトがデータ セグメントの先頭を形成します」)。次に、プロセスのメモリ イメージを作成するときにパッチを絶対アドレスに格納するのは、オペレーティング システムのプログラム ローダーです。
「ローカル」変数を使用すると、物事はより簡単になります。これらは、コンパイル時に決定できるスタックへの単なるオフセットであり、リンカーはそれらとは何の関係もありません。
(「静的」ローカル変数は読者の演習として残しておきます :-)
それが役に立ったことを願っています。