リンカとは何ですか?

この記事はより大きいシリーズの一部です – すべてをプログラムする方法:コアルールブック  (親シリーズ

序文

アセンブリーやCのような低レベルや中間レベルの言語では、ある時点でおそらく “リンカー”について心配するでしょう。おそらく、エラーがあり、シンボルが見つからないことがあります。 この神秘的なリンカーとは何ですか?それは何ですか? 高水準言語、特にPythonのようなインタープリタ言語の場合、pygameのようなソースからの拡張をコンパイルしていない限り、おそらくこれに遭遇することはありません。 PHPでは、dl()コマンドを使ってプログラムを実行しているときに、ライブラリをPHPランタイム環境に動的にロードまたはリンクすることができます。 私は本当にリンカとそれが何をするのか、また自分がLinuxマシンでアセンブリを勉強し始めたときにそれがどうなるのかを本当に知っていました。

リンカーはどこで使用しますか?

リンカーの役割を理解するためには、コンパイルプロセスを再考する必要があります。 私は以下の記事「解釈と編集」の記事からコンパイルプロセスダイアグラムを借りています。

ここでは、「実行可能ファイルにリンクする」ステップが表示されます。 これがリンカの入り口です。コンパイラは、オブジェクトコードファイルとして知られているものを出力します。 これらのファイルは、実行可能なマシンコードではありません。 代わりに、どのシンボルがどのマシンコードに対応しているかについてのタグと情報を持つプログラムの一部です。 上の図に正確に描かれていないリンカはこれらのオブジェクトコードファイルを受け取り、すべてのシンボルを「接着」するので、オブジェクトファイル内で見つかると一致するマシンコードに解決されます。 私はさらに説明しますが、最初に以下のリンクプロセスの詳細な図があります:

Cプログラムなどのプログラムを書くときには、プログラムの一部またはモジュールを別々のファイルに書き込むことがよくあります。 これらのファイルは、関数、グローバル変数、マクロなどを定義します(関数またはグローバル変数には、私のProgramming Crash Courseのポストを参照してください)。 これらのプログラムファイルをコンパイラに送信すると、各ファイルの各定義に対して適切なマシンコードが生成され、通常、各ファイルに対して、各定義(この時点ではシンボルと呼ばれます)に対応するファイルが生成されます 生成されたマシンコード。 ただし、プログラムはこの時点で実行可能ではありません。

2つのプログラムファイルFileOneとFileTwoがあるとします。 それぞれ次のように独自の関数を定義します。

コンパイラがこれらの各ファイルをコンパイルすると、オブジェクトコードが作成されます。各オブジェクトコードファイルには、メインのFileOneとanotherFunctionのFileTwoのmyFunction、およびプロセッサが実行する対応するマシンコードのシンボルのリストがあります。 FileOneは、myFunction()内のanotherFunction()を呼び出します。つまり、FileOneのコンパイラによって生成されたオブジェクトファイルに、欠けている部分があります。 FileOneのオブジェクトコードにはanotherFunctionとその対応するマシンコードが定義されていません。プロセッサはどのように処理すべきかを知る予定ですか?

これはリンカーが入る場所です。ファイルの両方を取り、main、myFunction、およびanotherFunctionのすべてのシンボルを識別します。次に、すべての対応するマシンコードをmyFunction内のanotherFunctionへの呼び出しを実行可能ファイル内の適切なメモリアドレスで満たす1つのファイルに配置します。それはすべてのファイルとそれに対応するマシンコードのすべてのシンボルを知っているので、これを行うことができます。

なぜリンカを使用するのですか?

リンカーを使用する理由はたくさんあります。それらのほとんどはプログラムコードの編成と関係しています。第一の理由は、私たちが書いたコードであるプログラムコードを別々のファイルに分割することができるということです。これにより、プログラマは、ユーザフレンドリーな方法でコードを編成するだけでなく、関連する機能をまとめてモジュールと呼ばれるものを形成するだけでなく、複数のプログラマがより簡単に作業できるようになります。異なるプログラム機能が異なるモジュール/ファイルに書き込まれている場合、あるプログラマーは他のファイルを妨害することなく1つのファイルを処理できます。一方、プログラムが1つの巨大ファイルにあった場合、ひどい。このシナリオの各プログラマーは、前のプログラマーがファイルの編集を完了するまで待つ必要があります。それがどのように非生産的であるかを見ることができます。これに加えて、GitやSubversionのようなソースバージョン管理プログラムは、変更を追跡する際に複数ファイルアプローチを利用しています。

リンカーを使用する別の理由は、リンカーを使用して、一般的にライブラリと呼ばれるものを使用できることです。プログラムライブラリは、何らかの種類のインタフェース(通常、機械コードへの関数やエントリポイントの束、またはオブジェクト指向の場合は、この執筆時点でBootstrap Part 2で扱うクラス)を公開するコードの束です。何かをする機械コードの束。この意味でのインタフェースは、他のプログラムがその追加機能を得るために参照できるシンボルの束です。これはC言語でプログラミングしているときに最も顕著で、C標準ライブラリを使用します。 C言語そのものを指定言語として使用すると、他の多くの言語と同様に入出力演算子などの多くの機能は定義されず、リンクされている標準ライブラリにそのタイプの機能が置かれます。 Cプログラムがコンパイルされてリンクされると、リンカーはライブラリのオブジェクトコード内のライブラリシンボルをルックアップし、空白を埋め込みます。これは、例えばグラフィックスを扱わなければならないような任意のライブラリに対して当てはまります。

注:これまで説明したことは静的リンクと呼ばれ、最終実行可能ファイルにはすべてのソースから必要なすべてのマシンコードが含まれ、独立して実行されます。 いくつかのオペレーティングシステムとリンカは、ダイナミックリンクを実行するオプションを持っています。ダイナミックリンクは、プログラムが実行されるときにダイナミックライブラリがメモリにロードされ、既存のプログラムとリアルタイムでリンクされます。 したがって、これらのプログラムは、それらが実行される前にそれらの中に未知の記号を有する。

ダイナミックなリンクはプロにあります。それは、実行時に複数の実行可能ファイルがリンクされている間に、ダイナミックライブラリをコンピュータのどこかに格納しておくだけです。 しかし、この方法には欠点があります。つまり、ダイナミックライブラリが後方互換性のない方法でアップグレードまたは書き換えられ、システム内で置き換えられた場合、以前のすべてのプログラムが中断して実行されません。 これは、静的にリンクし、すべてのマシンコードを独立して持っていれば発生しません。

リンカの別の、より難解な機能は、再配置と呼ばれるものです。通常、オブジェクトファイルは、外部の別のオブジェクトファイルで使用される可能性のあるすべてのシンボルを定義しますが、内部使用のシンボルも定義します。これらのシンボルは、再配置と呼ばれるプロセスでリンカーによって変換およびフィルタリングされます。このプロセスは次のようなものになります。コンパイラは最終出力のマシンコードの最終レイアウトを知る手段がないため、コードのレイアウトによってはより効率的な命令を利用できません。したがって、コンパイラは、最も機械的な命令を生成します。これは、最終的なマシンコードレイアウトで最も遅くて効率的ではありませんが、リラクゼーションヒントとして知られています。すべての入力オブジェクトが読み込まれ、一時アドレスが割り当てられると、リンカはアドレスを再割り当てするリラクゼーションパスを実行し、コンパイラが作成した控えめな推測に対してより効率的な命令を置き換えることができます。これにより、さらなる緩和などが可能になる可能性があります。一般的に、リンカやコンパイラを実装していない平均的なプログラマは、これらの問題を安全に考慮することができません。リンカーがそれを処理します。

結論

リンカはソフトウェア開発プロセスの不可欠な部分であり、プログラマは意味のある方法でコードを分けることができます。 また、他のプログラムで使用するために生成されたプログラミングライブラリを使用することもできます。 C標準ライブラリはそのようなライブラリの一例であり、標準のCプログラムがそのコードにリンクして一般的な入出力などの操作を実行できるようにします。 コンパイル時にリンカーがないと、すべてのプログラムを1つの巨大なモノリシックファイルとして記述する必要があります。 1つのプログラムで複数のプログラマーが作業していた場合、それぞれが同じファイルで自分の目標を追求する前に、もう一方のプログラムが完了するのを待たなければなりません。 複数のファイルを1つの実行可能ファイルにまとめることができるリンカでは、これは不要です。 私はこの記事があなたのためにリンカが何をしているのかをはっきりと願っていますが、何か質問があればコメントに残すことができます。 読んでくれてありがとう!

この記事はより大きいシリーズの一部です – すべてをプログラムする方法:コアルールブック  (親シリーズ

この記事を読んでいただければ、パトリオンのサポートを検討することもできます。

しかし、毎月の約束が少しでもあれば、私はそれを得る、あなたは私にコーヒーを買うことを考えるかもしれない。

photo credit: xmodulo Shared Library Info via photopin (license)

Liked it? Take a second to support kadar on Patreon!

あわせて読みたい

コメントを残す

%d人のブロガーが「いいね」をつけました。