今日学んだこと#
CPUが命令を実行する際、処理対象データの位置を指定する「アドレス指定方法」について学びました。即値・直接・間接・指標・基底・相対・レジスタ・レジスタ間接の8種類があり、それぞれ速度・柔軟性・用途が異なります。
学習内容#
アドレス指定方法とは#
コンピュータの命令は「命令部」と「アドレス部(オペランド)」から構成されています。アドレス指定方法とは、オペランドからデータの実際の格納場所(有効アドレス)を求める方式のことです。
8種類のアドレス指定方法#
1. 即値アドレス指定#
アドレス部の値がメモリアドレスではなく、演算対象のデータそのものである方式です。
命令
+------+------+
| 命令 | データ | ← このデータ(オペランド)を直接使う
+------+------+
メモリアクセスが不要なため高速ですが、命令内にデータを埋め込むため表現できる値の範囲が制限されます。
2. 直接アドレス指定#
命令のアドレス部に、有効アドレスが直接書き込まれている方式です。
命令 主記憶
+------+---------+ +-------------+
| 命令 | アドレスA | ------------> | データ | ← 目的のデータ
+------+---------+ +-------------+
アドレスA
構造がシンプルですが、指定できるメモリアドレスの範囲がアドレス部のビット数に依存します。
3. 間接アドレス指定#
命令のアドレス部が指すメモリ番地に、有効アドレスが格納されている方式です。
命令 主記憶
+------+---------+ +-------------+ +-------------+
| 命令 | アドレスA | ------------> | アドレスB | ------------> | データ |
+------+---------+ +-------------+ +-------------+
アドレスA アドレスB
広いメモリ空間にアクセスできますが、メモリアクセスが2回発生するため処理速度が遅くなります。
4. 指標アドレス指定(インデックスアドレス指定)#
命令のアドレス部の値とインデックスレジスタの値を加算して有効アドレスを求めます。
命令 インデックスレジスタ
+------+---------+ +-------------+
| 命令 | アドレスA | | 値X |
+------+---------+ +-------------+
| |
+--------> 加算 <---------+
|
↓
有効アドレス (A+X)
配列など連続したデータ領域へのアクセスに便利です。インデックスレジスタの値を変更するだけでアクセス先をずらせます。
5. 基底アドレス指定(ベースアドレス指定)#
命令のアドレス部の値とベースレジスタの値を加算して有効アドレスを求めます。
命令 ベースレジスタ
+------+---------+ +-------------+
| 命令 | 変位A | | 基準値B |
+------+---------+ +-------------+
| |
+--------> 加算 <-----------+
|
↓
有効アドレス (B+A)
プログラムの再配置を容易にします。ベースレジスタにプログラムの先頭アドレスを入れておくことで、プログラムをメモリ上のどこに移動しても命令を書き換える必要がありません。
6. 相対アドレス指定#
命令のアドレス部の値とプログラムカウンタの値を加算して有効アドレスを求めます。
命令 プログラムカウンタ
+------+---------+ +-------------+
| 命令 | 変位A | | 現在位置P |
+------+---------+ +-------------+
| |
+--------> 加算 <---------+
|
↓
有効アドレス (P+A)
主に分岐命令で使われ、現在の命令位置からの相対的なジャンプ先を指定します。
7. レジスタアドレス指定#
オペランド部で指定したレジスタの値を直接データとして使う方式です。
命令 CPU内部レジスタ群
+------+----------+
| 命令 | レジスタA | ------------> +-------------+
+------+----------+ | データ | ← 目的のデータ
+-------------+
CPU内部で完結するため極めて高速ですが、レジスタの数は限られています。
8. レジスタ間接アドレス指定#
オペランド部で指定したレジスタに、有効アドレスが格納されている方式です。
命令 CPU内部レジスタ群 主記憶
+------+----------+
| 命令 | レジスタA | ------------> +-------------+ +-------------+
+------+----------+ | アドレスB | ------------> | データ |
+-------------+ +-------------+
アドレスB
間接アドレス指定ではメモリアクセスが2回必要でしたが、レジスタ間接ではメモリアクセスは1回で済みます。ポインタを利用した処理で高い柔軟性を発揮します。
まとめ#
| アドレス指定方法 | 有効アドレスの求め方 | メモリアクセス | 特徴・用途 |
|---|---|---|---|
| 即値 | データそのもの | 0回 | 高速、定数の指定 |
| 直接 | アドレス部の値 | 1回 | シンプル |
| 間接 | アドレス部が指す番地の値 | 2回 | 広いアドレス空間 |
| 指標 | アドレス部 + インデックスレジスタ | 1回 | 配列アクセス |
| 基底 | アドレス部 + ベースレジスタ | 1回 | プログラム再配置 |
| 相対 | アドレス部 + プログラムカウンタ | 1回 | 分岐命令 |
| レジスタ | レジスタの値がデータ | 0回 | 最高速 |
| レジスタ間接 | レジスタの値がアドレス | 1回 | ポインタ操作 |
- 速度重視なら即値・レジスタアドレス指定(メモリアクセス0回)
- 柔軟性重視なら間接・レジスタ間接アドレス指定
- 指標と基底は加算する対象が異なる(配列操作 vs プログラム再配置)