FE EXAM

アドレス指定方式(アドレッシング)

オペランドから実効アドレスを求める方法(即値・直接・間接など)

DIAGRAM
オペランド部メモリ実効アドレス/値

5つのアドレス指定方式と実効アドレスの求め方

即値アドレス指定オペランド = 値そのもの命令コードオペランド部#5(値)値 5 をそのまま使用メモリ参照 0 回オペランド部に値そのものを書く。メモリ参照なし 直接アドレス指定実効アドレス = オペランド命令コードオペランド部300(番地)メモリ[300]= データ実効アドレス = 300オペランド部がそのまま参照先の番地 間接アドレス指定実効アドレス = メモリ[オペランド]命令コードオペランド部300メモリ[300]= 500メモリ[500]= データ実効アドレス = 500オペランドが「番地が入った番地」を指す インデックスアドレス指定実効アドレス = オペランド + 指標レジスタ命令コードオペランド部200(ベース)指標レジスタ= 8実効アドレス200 + 8 = 208ベース番地に指標レジスタの値を足す 相対アドレス指定実効アドレス = PC + オペランド命令コードオペランド部+12(差分)PC(基準)= 100実効アドレス100 + 12 = 112現在のPC(基準点)からの差で番地を求める
解説

📌
アドレス指定方式とは

オペランド部300求める実効アドレス実際に使う番地求め方のルールがアドレス指定方式

アドレス指定方式(アドレッシング)とは、命令のオペランド部に書かれた情報から、実際にアクセスするメモリの番地(実効アドレス)をどう求めるかを決める方法のことです。実効アドレス=CPUが最終的に「ここを読み書きする」と決める番地のことです。

同じ「300」という数がオペランド部に書かれていても、方式が違えば意味がまったく変わります。「値そのものなのか」「番地なのか」「番地が入った番地なのか」など、解釈のルールを切り替えるのがアドレス指定方式です。上の図解で、5つの方式が同じオペランドをどう扱うか比べてみてください。

身近な例で言うと、メモに「3」と書いてあったとき、「3個ください(値)」なのか「3番の棚(番地)」なのか「3番の棚に貼ってある住所の場所(間接)」なのか──読み方の取り決めが必要ですよね。アドレス指定方式は、まさにその取り決めにあたります。

🗂️
5つの方式の概要

代表的な5つの方式を整理します。それぞれ「オペランド部の数をどう解釈するか」が違います。

方式オペランドの意味実効アドレスの求め方
即値値そのもの番地ではなく値を直接使う(参照なし)
直接参照先の番地実効アドレス = オペランド
間接番地が入った番地実効アドレス = メモリ[オペランド]
インデックス(指標)ベース番地実効アドレス = オペランド + 指標レジスタ
相対基準点からの差実効アドレス = PC + オペランド

それぞれの特徴を一言でまとめると次のとおりです。
即値:値が命令の中にある。最速だが固定の定数しか扱えない
直接:オペランドがそのまま番地。分かりやすいが表せる番地の範囲が限られる
間接:番地のさらに先を参照(ポインタ)。柔軟だがメモリアクセスが増える
インデックス:ベース+指標レジスタ。配列の要素アクセスに最適
相対:PCからの差分で指定。プログラムをどこに置いても動く(位置独立)

身近な例で言うと、即値は「りんご3個」、直接は「3番の棚」、間接は「3番の棚に書いてある住所の場所」、インデックスは「200番地から8つ目」、相対は「今いる場所から12先」と考えると区別しやすくなります。

🔢
メモリ参照回数で方式を比べる

実際のデータを得るまでのメモリ参照回数即値(参照なし・値を直接使用)直接1回インデックス1回相対1回間接2回間接指定は2回 → 最も時間がかかる

各アドレス指定方式では、「実際に使いたいデータ」にたどり着くまでのメモリへのアクセス回数(=参照回数)が異なります。参照回数が多いほど時間がかかるため、方式の選択は処理速度に直結します。

参照回数ごとの方式をまとめます。
0回(即値):オペランドの値をそのまま使う。命令の中に値が書いてあるので、メモリを読みに行く必要がない。最速
1回(直接・インデックス・相対):求まった番地のメモリを1回読めばデータが手に入る
2回(間接):まずオペランドが指す番地を読んで「本当の番地」を得て、その番地をまた読む。2段階なので最も遅い

なぜ間接指定を使うのか。遅いのに使う理由があります。間接指定はオペランドを書き換えなくてもアクセス先を変えられるため、プログラムを書き換えずに動的にアドレスを変更したい場面で有効です。ポインタ(=番地を格納した変数)と同じ考え方です。身近な例で言うと、「Aさんの住所は引き出しの中の紙に書いてある」という状況で、引き出しの中の紙を差し替えるだけで届け先が変えられるイメージです。

🗃️
インデックスと相対 — なぜ加算するのか

インデックス — 配列の要素を順番に取り出す番地200a[0]番地201a[1]番地202a[2]番地203a[3]番地204a[4]ベース200 + 指標レジスタ=2 → 番地202 = a[2]相対 — プログラム内でのジャンプ先を指定する番地90番地100番地110番地120PC=100 + オペランド=+20 → 番地120 へジャンプ

インデックスと相対は、どちらも「ある基準点にオペランドの値を足して」実効アドレスを求めます。なぜ加算するのかを理解すると、それぞれの使いどころが見えてきます。

インデックスアドレス指定(指標アドレス指定)は、配列(=同じ種類のデータを連続した番地に並べたもの)へのアクセスに最適です。
・オペランドにベース番地(配列の先頭番地)を書き、指標レジスタ(=計算に使う汎用の記憶場所)に何番目の要素か(添え字)を入れる
ベース + 添え字 = その要素のアドレスが自動で求まる
・ループのたびに指標レジスタを1ずつ増やすだけで配列を順番に走査できる

相対アドレス指定は、PC(プログラムカウンタ=次に実行する命令の番地を保持するレジスタ)を基準にします。
・「今いる場所から何番地先へ飛ぶ」という形で分岐(if文など)のジャンプ先を指定できる
・プログラムをメモリ上のどのアドレスに置いても、PC相対の差は変わらないため正しく動作する(これを位置独立コードと呼ぶ)

身近な例でまとめると、インデックスは「本棚の5列目から3冊目を取る」(基準 + 番号)、相対は「今の場所から2ブロック先の角を曲がる」(現在地 + 差分)という指示に相当します。直接番地を書く方式と比べて、変化に強い柔軟な指定方法です。

📐
実効アドレスの求め方

実効アドレスとは、CPUが最終的にアクセスするメモリの番地のことです。アドレス指定方式が違うと、同じオペランド「300」からでも求まる実効アドレスが変わります。具体的に計算してみましょう。

前提: オペランド = 300、メモリ[300] = 500、
   指標レジスタ = 8、PC = 100
─────────────────────────
直接   : 実効アドレス = 300
間接   : 実効アドレス = メモリ[300] = 500
インデックス: 実効アドレス = 300 + 8 = 308
相対   : 実効アドレス = 100 + 300 = 400
即値   : 実効アドレスなし(値300をそのまま使用)

求め方のポイントを整理します。
即値:そもそも番地を求めない。オペランドの値そのものを使う(メモリ参照0回)
直接:オペランドをそのまま実効アドレスとする(メモリ参照1回)
間接:オペランドが指す場所の中身を読み、それを実効アドレスとする(メモリ参照2回)
インデックス・相対:オペランドにレジスタ(指標)やPCの値を加算して実効アドレスを求める

それぞれの方式の特徴を整理すると次のとおりです。
間接指定はメモリを2回読む(最も時間がかかる)
インデックスは配列アクセス(ベース番地+要素番号)に便利
相対はプログラムの再配置(どこに置いても動く)に有利
というように、それぞれの「足し算の中身」と「メモリ参照回数」をセットで理解すると区別しやすくなります。

関連コンテンツ