アドレッシングモード(Addressing Mode)は、CPUの命令セットアーキテクチャ(ISA)の一部を構成する。プロセッサの命令には操作対象をオペランドで指定するものがあり、その指定方法の詳細がアドレッシングモードと呼ばれるものである。したがって、広義のアドレッシングモードにはレジスタを指定する場合も、値が命令のオペランドとして直接与えられている場合も含まれるが、狭義のアドレッシングモードはオペランドとして使用すべきメモリ領域を指定するものとみなされる。
アドレッシングモードに関心があるのはコンパイラを開発する人とアセンブリ言語を直接使用する人であろう。アドレッシングモードは様々なものがISA毎に存在するが、共通の名称は存在しない。したがって、本項目で便宜的に採用している呼び方があらゆる場面で通用するわけではない。アドレッシングモードの具体的な指定方法もISAによって異なる。例えば、DECのVAXでは、オペランドであらゆるアドレッシングモードを指定している。したがって MOV 命令は一種類だけでレジスタ間の転送もレジスタ・メモリ間の転送もメモリ間の転送も行うようになっている。それに対してRISCアーキテクチャでは命令コード側にオペランドの意味を規定する情報が含まれている。例えばMIPSアーキテクチャのロード命令は転送サイズごとに命令コードがあり、メモリ→レジスタという転送だけを扱う。
目次
1 構成要素
2 CISCのアドレッシングモード
3 RISCのアドレッシングモード
4 既に使われなくなったアドレッシングモード
4.1 初期のコンピュータ
4.2 多重メモリ間接
4.3 メモリマップド・レジスタ
//
アドレッシングモードとは、単にアクセスすべきアドレスを指定する方法を意味するのではなく、命令のオペランドの記述方法そのものである。addressing とは「演算対象を指定する」ことを意味する。したがって、アドレッシングモードにはメモリアドレスの指定方法だけでなく、レジスタそのものや演算にそのまま使われるイミディエイト値も含まれる。アドレッシングモードを構成する要素として以下のようなものがある。
レジスタ
命令のオペランドとしてレジスタそのものを指定する場合と、指定されたレジスタの内容をメモリアドレス指定に使用する場合がある。以下に列挙するのはアドレッシングモードでメモリアドレス指定に使われるレジスタであるが、あくまでもアドレッシングモードでの役割名であり、下記の名称のレジスタが必ず存在するわけではない。
ベースポインタ(BP)/ベースレジスタ(BR)
アクセスすべきメモリアドレスを格納するレジスタ。さらにメモリブロック(例えばC言語の構造体など)の先頭アドレスを保持して、ディスプレースメント(後述)を使用してメモリブロック内の任意のアドレスを指定するのにも使われる。
インデックスレジスタ(IX)
配列のインデックスに相当する値を保持するレジスタ。単独で使われることはなく、ディスプレースメントの変数化したものと捉えることができる。
プログラムカウンタ(PC)
実行中の命令のアドレス(あるいは一般に次に実行予定の命令のアドレス)を保持するレジスタ。アドレッシングモードの文脈では、プログラムの流れを制御する際(分岐命令など)に使われる特殊なベースポインタである。
イミディエイト/即値
命令内に直接書かれている値を意味する。演算命令などのオペランドとしてそのまま使われる。以下に列挙するものは命令内に直接書かれアドレッシングモードでメモリアドレス指定に使われる値である。
直接アドレス
アドレスを命令内で直接指定する場合に使われる。例えば大域変数のアドレスやライブラリ関数のアドレスなどは直接アドレスで指定されることが多い(ただし、ダイナミックリンクされるライブラリのアドレス指定はその限りではない)。
ディスプレースメント/オフセット
何らかのベースアドレスからのオフセットを示す値である。
なお、インデックスレジスタはその性格上、必ずしもメモリアドレス全体を表せるビット幅を持つ必要はないが、一般的にはアドレス全体を表すことができるため、ベースポインタとの役割分担があいまいとなっている。
CISCアーキテクチャでは、分岐命令やメモリアクセス(ロード/ストア)命令だけでなく、演算命令などでもメモリアクセスを行うことができる。CISCの命令セットの設計思想はアドレッシングモードを豊富に用意して、ある処理を実現するのに必要となる命令数を減らすことが大きな目標となっていた。このため、現在では使われなくなった複雑なアドレッシングモードを用意したCPUも存在する(VAXが有名。日本では日本電気のV60などは豊富なアドレッシングモードを誇っていた)。x86アーキテクチャのアドレス指定方式
右図は、現在最も多く使われているCISCであるx86アーキテクチャでのアドレッシングモードを示している。実効アドレス(実際にアクセスすべきメモリアドレス)はセグメント内のアドレスであり、セグメントレジスタと組み合わせることでリニアアドレスと呼ばれる一種の論理アドレスに変換されるが、この部分はメモリ管理に関わるものでアドレッシングモードには含まれない。実効アドレスは、ベースレジスタ、インデックスレジスタ、ディスプレースメントを加算することで得られるが、これらの要素は省略可能である。したがって、以下のようなアドレッシングモードが存在する。
レジスタ間接
ベースレジスタがアクセスすべきメモリアドレスを保持している。また、ベースレジスタを省略してインデックスレジスタだけを使う場合もこれにあたる。
レジスタ間接・インデックス付き
ベースレジスタにインデックスレジスタの値を加算した値がアクセスすべきメモリアドレスとなる。インデックスレジスタの値は加算する前に2倍、4倍、8倍とスケーリングすることができる。これは例えば 32ビットのデータの配列のインデックスをインデックスレジスタに保持している場合に、4倍にスケールアップすることで配列先頭からのオフセット(アドレスの差分)に変換されるような場合に使われる。
レジスタ間接・ディスプレースメント付き
ベースレジスタ(またはインデックスレジスタ)に命令内に直接書かれたディスプレースメントを加算した値がアクセスすべきメモリアドレスとなる。
レジスタ間接・インデックス付き・ディスプレースメント付き
全部を使用した指定方法
直接アドレス
ディスプレースメントのみを使用した場合。
x86では、ロード・ストア命令以外でもメモリアクセスが可能である。例えば加算の場合「A ← A + B」という形式であるため、A にメモリを指すようなアドレッシングモードを使用すると一命令で「ロード→加算→ストア」と二回のメモリアクセスを行うことになる。