FromNandの日記

自分的備忘録

再配置可能コード(リロケータブルコード)と位置独立コード(PIC)の違いと解説

【解説】

そもそも、なんでこれらが必要になったのか?

それは、昔はMMU(動的アドレス変換)などがなかったので、絶対アドレスを指定してしまうと、本当にそのアドレスでしか実行できなかった。

これは、アドレスが重複する2つのプログラムが同時に実行できないことを意味する。

これは相当不便だったので、どのアドレスにおいても実行できるような機械語が欲しくなる。

 そこで再配置可能コードと位置独立コードの出番である。

 

再配置可能コード(リロケータブルコード)は、指定されたアドレスで実行可能にするためにリンカやローダが特別な処理を施す。

具体的には、リンクの時点では絶対アドレスを指定する部分を開けておいて、実行時にロードするアドレスを埋めるとかだろう。

こういった処理を行うことで、どのアドレスに置いても実行可能にすることができる。

 

しかし、位置独立コードでは、こういったリンカ・ローダの処理を行わずに、メモリに展開し実行することができる。

位置独立コードを生成するためには、コンパイラがいくつかの命令をサポートしていなければならない。

例えば、絶対アドレスを指定する分岐命令といった特定のメモリアドレスを参照する命令は、等価なプログラムカウンタ相対命令に置き換えなければならない。

そのために命令数が増えることもあるので効率は低下するが、最近のプロセッサはその差が無視できる程度になるよう設計されている

 

しかし、最近はMMUなどのハードが充実し、位置独立コードの意義が薄れてきた。

一般的に、位置独立コードより位置依存コードのほうが高速なので、MMUを使用することがよりよい解決策だったらしい。

 

次に解決すべき課題は、複数の似たようなジョブを同時に実行する際、同じコードを複数回ロードしなければならず、メモリを無駄に使用することになる点である。

全く同じプログラムを動作させる2つのジョブがあるとき、動的アドレス変換では物理メモリ上にロードしたプログラムを2つのジョブの仮想アドレス空間マッピングすることで、1つのプログラムのコピーがメモリ上には1つしかないようにすることができる。

これには、再配置可能コードではなく、位置独立コードを使用する必要がある。

なぜなら、再配置可能コードでは絶対アドレスを使用するが、これは異なるベースアドレスを指すセグメントでは正しく動作しない。

位置独立コードでは、相対アドレス命令によってこれを回避できるからである。

 

 

【結論】

・再配置可能コードは実行するために、リンカやローダによる特殊な処理を必要とするが、位置独立コードはそうではない。

・一般に位置独立コードより、位置依存コードのほうが高速。

>>> 絶対ジャンプのほうが相対ジャンプより高速だから?

・すなわち、再配置可能コードのほうが位置独立コードよりも高速。

>>> 再配置可能コードは、実行前に絶対アドレスがコードに組み込まれるため。

・最近ではMMU(動的アドレス変換)が位置独立コードの代わりをすることが多くなったので、位置独立コードはほとんど不要になった。

・共有ライブラリなどで、位置独立コードは使用されている。

 

【参考URL】

https://ja.wikipedia.org/wiki/%E4%BD%8D%E7%BD%AE%E7%8B%AC%E7%AB%8B%E3%82%B3%E3%83%BC%E3%83%89