基本情報のアドレス指定方式は、方式名だけを覚えても、表からどの数値を選ぶかで迷いやすいテーマです。命令に書かれた「100」が、データそのものなのか、データの番地なのか、基準からのずれなのかによって、答えが変わります。
解くときは、先に方式に従って実効アドレスを決め、データの値を問われた場合だけ、その番地の内容を取り出します。即値指定とレジスタ指定では、データを使うために主記憶の番地を求める必要がありません。
この記事では、即値・直接・間接・相対・ベース・インデックス・レジスタ指定の違いを整理し、同じメモリ表を使った例題で計算します。16進数や負の変位、プログラムカウンタの基準を読み違えない手順も確認しましょう。
- 実効アドレスと取り出すデータを別々に答える方法
- 即値・直接・間接を同じ指定値から追い分ける考え方
- 相対・ベース・インデックスで加える値の選び方
- 16進数と負の変位を含む例題の確認手順
基本情報のアドレス指定方式の違い

実効アドレスとデータを分ける
アドレス指定方式は、命令が処理対象のデータをどのように指定するかというルールです。アドレッシングモードとも呼ばれます。主記憶のデータを扱う場合、方式に従って最終的に参照する番地を求めます。この番地が実効アドレスです。有効アドレスという表記でも、ここでは同じ意味で扱います。
命令の「何をするか」を表す部分が命令部で、「何を対象にするか」を表す指定がオペランドに当たります。対象を指定する部分には、定数、番地、レジスタ番号などが入ります。入っている数字をすべてメモリの番地と決めつけないことが、読み解く出発点です。
ここで扱うアドレスは、CPUが主記憶のどこを参照するかを表す番地です。機器をネットワーク上で識別するIPアドレスや、サブネットマスクの計算とは別の話になります。試験の問題文に命令語・レジスタ・主記憶が出てきたら、まずCPU内部のデータ指定として読みましょう。
以下では、命令のアドレス部の値をA、実効アドレスをEA、番地aに格納されたデータをM[a]と書きます。M[100]は「100番地の内容」という意味です。レジスタの内容はR、PCの内容はPC、ベースレジスタの内容はB、インデックスレジスタの内容はXとします。
例えば100番地に350が格納されているなら、M[100]=350です。この時点で、番地100と内容350は別のものですよね。さらに350番地に42が入っていれば、M[350]=42となります。350を番地として使うか、値として使うかは、指定方式によって決まります。
実効アドレスを尋ねる設問では、最終的な参照先を決めたところで答えます。一方、「取り出されるデータ」「レジスタへ格納される値」なら、ロード命令などの動作に従って、その先の内容まで読みます。以降のデータ比較例は、指定したオペランドを読み出す命令を前提にしています。
即値・直接・間接を追い分ける
即値アドレス指定方式は、命令中の値をデータそのものとして使います。A=100なら、使うデータは100です。「100番地を開いて内容を取る」という処理はありません。例えば定数をレジスタに入れる場面なら、命令に記述された100をそのまま格納します。
直接アドレス指定方式では、AをそのままEAにします。A=100ならEA=100で、データを読む命令が取り出すのはM[100]です。先ほどの例なら350になります。命令に100と書かれていても、使うデータが100とは限りません。
「直接」という名前があるから値を直接使う、と覚えると即値と混同します。直接指定は、データが置かれている番地を直接示す方式です。「命令にデータがあるのが即値」「命令にデータの番地があるのが直接」と、何が命令の中にあるかで分けると区別できます。

間接アドレス指定方式では、Aが示す番地の内容を読み、その内容をEAにします。A=100、M[100]=350なら、EA=350です。データを読み出すときは、さらに350番地へ進んでM[350]=42を取り出します。
この流れを短く書くと、直接は「100→M[100]=350」、間接は「100→M[100]=350→M[350]=42」です。間接で最初に読んだ350は、この命令では目的のデータへ進むための番地として使われます。そこで止まると、実効アドレスには答えられても、取り出すデータには答えられません。
反対に、実効アドレスを問われているのに42まで進めるのも誤りです。間接指定のEAはM[A]であり、M[M[A]]はそのEAから取り出すデータです。式の外側にMをもう一つ付ける前に、設問がどちらを求めているか確認してください。

図で間接指定を判定するときは、主記憶への矢印があるというだけでは不十分です。命令がまず主記憶のある番地を示し、そこに格納された値が別の番地を示しているかを追います。CPU・主記憶・レジスタの枠の配置が違っても、この関係は変わりません。
直接と間接でデータを取り出す経路の違いは、京都大学の計算機工学講義資料のアドレス指定モードでも確認できます。以下の数値例は、経路を追う練習用に作成した独自の例です。
レジスタ指定は中身の役割で判断
レジスタは、CPU内で値を保持する記憶場所です。レジスタ指定方式、またはレジスタ直接指定方式では、命令に示されたレジスタの内容をデータとして使います。例えばR2の内容が350なら、対象データは350です。主記憶の350番地へ進む必要はありません。
命令に書かれた「R2」の2はレジスタを選ぶ番号であり、使うデータが2という意味でも、主記憶の2番地を読むという意味でもありません。レジスタ番号とレジスタの内容を別に読むことが大切です。表でR0からR3までの値が与えられたら、指定されたレジスタの行だけを選びます。
対比として知っておきたいのが、レジスタ間接指定方式です。こちらはレジスタの内容を主記憶の番地として使います。R2=350ならEA=350で、データを読み出す命令ならM[350]を取り出します。M[350]=42なら、答えは42です。
レジスタ指定の350とレジスタ間接指定の42は、同じR2から始めても一致しません。前者はR2の中身を対象データとして使い、後者はR2の中身を参照先として使うからです。「レジスタが登場する方式は、全部レジスタの中身が答え」とまとめないでください。

また、主記憶を使う間接指定とレジスタ間接指定も経路が違います。主記憶の間接指定はM[A]を読んでEAを得ますが、レジスタ間接指定はRをEAとします。どこに参照先の番地が保存されているかを見ると、二つを見分けられます。
指定形式と読み出し先の区別は、中部大学のZ80講義資料のアドレス方式でも示されています。CPUによって命令の表記や使える形式は異なるので、特定の命令記号より「中身をデータにするか、番地にするか」を先に押さえましょう。
相対・ベース・インデックスの違い
相対・ベース・インデックスはいずれも、命令中の値とレジスタの内容を加えて実効アドレスを求める方式です。足し算自体は同じでも、加えるレジスタと、その役割が違います。レジスタ表に数値が何個もあるときは、方式名から使う行を決めます。
相対アドレス指定方式は、PCの内容を基準にします。PCはプログラムカウンタのことで、命令を実行する位置を管理するレジスタです。命令中の値が基準からの変位なら、EA=PC+Aと表せます。PC=500、A=40ならEA=540です。
相対指定は、プログラム内の近い位置へ分岐するときなどに使われます。基準となる命令位置と目的位置を同じだけ移動させれば、両者の差は保てます。ただし、どの時点のPCを使うかは命令の仕様や問題の条件に従うため、「現在実行中の命令の先頭」を無条件に基準にしないことが必要です。
ベースアドレス指定方式は、ベースレジスタの内容を基準にします。基底アドレス指定方式とも呼ばれ、EA=B+Aです。B=1000、A=40ならEA=1040になります。領域の基準となる場所をBに保持し、そこからの位置を命令側で指定すると考えると分かりやすいです。
例えば同じ構造の領域を別の場所へ移す場合、基準位置を変えて、領域内の変位を保つことができます。ベース方式を相対方式と混同しないように、問題で明示された基底レジスタを選んでください。ここでの「相対」はPC基準の方式を指しています。
インデックスアドレス指定方式は、インデックスレジスタの内容を加えます。指標アドレス指定方式、指標付きアドレス指定方式という名称もあります。EA=A+Xです。A=1000、X=12ならEA=1012となり、連続するデータの中から対象を選ぶ場面と結び付きます。
ベースとインデックスの違いは、どちらも足し算だから数値からだけでは判別できません。基準となる領域の位置を持つのがベース、対象をたどるためのずれを持つのがインデックス、という役割を確認します。実際のCPUではより複雑な組合せもありますが、まず問題で指定された方式の式を使いましょう。
方式別の式とメモリ参照を整理
代表的な式を、データを読み出す命令という共通の前提で並べます。「主記憶のEAが不要」とした方式は、命令を読み出す処理自体が不要という意味ではありません。ここでは、処理対象のデータを指定して取り出す部分を比較しています。
| 方式 | 主記憶の実効アドレスEA | 対象データ | 判定の手掛かり |
|---|---|---|---|
| 即値 | 求めない | A | 命令中の値がデータ |
| 直接 | A | M[A] | 命令中の値が番地 |
| 間接 | M[A] | M[M[A]] | 番地の内容を次の番地にする |
| レジスタ | 求めない | R | レジスタの内容がデータ |
| レジスタ間接 | R | M[R] | レジスタの内容が番地 |
| 相対 | PC+A | M[PC+A] | PCを基準に加算 |
| ベース(基底) | B+A | M[B+A] | 基底レジスタを基準に加算 |
| インデックス(指標) | A+X | M[A+X] | 指標レジスタを加算 |
単純なモデルで、命令の読出しを除いて対象データを主記憶から取り出す回数を数えるなら、即値とレジスタ指定は0回、直接とレジスタ間接、加算でEAを求める各方式は1回、主記憶の間接指定は2回です。これは参照経路を数えたもので、実際の外部メモリ通信回数や実行時間を保証する数ではありません。
さらに、相対指定で分岐先を求める命令なら、求めた番地をPCへ設定する場合があり、対象データをM[EA]から読むロード命令とは動作が違います。アドレス指定方式の式と、命令そのものの動作を一緒に確認すると、表を丸暗記して当てはめる誤りを避けられます。
キャッシュの有無やアクセス時間を扱うときは、今回の参照経路とは別の条件が加わります。時間の計算まで復習したい場合は、基本情報のキャッシュメモリのヒット率と実効アクセス時間で、問題ごとの時間モデルを確認してください。
基本情報のアドレス指定方式の例題

同じメモリ表で三つの方式を比較
ここからは、方式を判定して計算する練習です。特に断りがない限り数値は10進数とし、指定された対象データを読み出す命令を考えます。CPUの詳細を再現するためではなく、番地と内容を分けて追うための学習用の表です。
最初の条件はA=100です。主記憶の内容を次のように与えます。空欄の番地や隣の番地を勝手に推測する必要はありません。指示された参照先が表のどの行に対応するかだけを確認します。
| 主記憶の番地 | その番地に格納された値 |
|---|---|
| 100 | 350 |
| 350 | 42 |
| 42 | 7 |
即値指定なら、対象データはAの100です。主記憶表に100番地が載っていても、この指定で参照する必要はありません。問題には使わない情報が含まれることもあるため、表の全数値を計算へ入れようとしないでください。
直接指定なら、EA=100です。「実効アドレスはどれか」の答えは100で、「読み出される値はどれか」の答えはM[100]=350です。350はこの命令が読むデータなので、さらに350番地へ進みません。
間接指定なら、最初にM[100]=350を読んで、EA=350と決めます。そのあと対象データを読み出すので、M[350]=42が答えです。42番地に7があることは、この1段の間接指定では使いません。読み出した値がたまたま表の別の番地として存在していても、再び参照する指示がなければ止まります。
| 方式 | 実効アドレス | 読み出される値 | ここで止まる理由 |
|---|---|---|---|
| 即値 | 主記憶のEAは不要 | 100 | 命令中の値を使う |
| 直接 | 100 | 350 | 100番地の内容が対象データ |
| 間接 | 350 | 42 | 350番地の内容が対象データ |
間違えたときは、計算を全部やり直す前に、答えの種類を確認すると原因が見つかります。直接指定で100をデータの答えにしたなら、内容を読む1段階が抜けています。間接指定で350をデータの答えにしたなら、EAを求めたところで止まっています。間接指定で7を答えたなら、指定されていない参照を1段階増やしています。
同じ100・350・42でも、文脈によって番地と値の役割が変わります。数字に「番地」「内容」のメモを添えて追うと、暗算での取り違えを減らせます。答えの選択肢を先に見て方式を推測するより、命令から順に辿る方が確認しやすいですよ。
相対・ベース・インデックスを計算
次はA=40、PC=500、B=1000、X=12という条件です。レジスタ表の「名前」と「内容」をセットで読み、方式に合った値だけを選びます。メモリ表はM[540]=80、M[1040]=90、M[52]=60とします。
相対指定のEAは500+40=540で、読み出す値は80です。ベース指定のEAは1000+40=1040で、読み出す値は90です。インデックス指定のEAは40+12=52で、読み出す値は60です。三つとも加算ですが、参照先が異なります。

| 方式 | 使うレジスタ | 実効アドレスの計算 | 取り出す値 |
|---|---|---|---|
| 相対 | PC=500 | 500+40=540 | M[540]=80 |
| ベース | B=1000 | 1000+40=1040 | M[1040]=90 |
| インデックス | X=12 | 40+12=52 | M[52]=60 |
ここでPC・B・Xをすべて足すのは誤りです。方式の式は、レジスタ表にある値を全部使うという意味ではありません。問題がベースとインデックスを組み合わせた命令を別途定義している場合には、その定義に従いますが、単独の方式を問うこの例では表の1行ずつが独立しています。
ベースの役割を確かめるなら、領域が移った場面を考えてみましょう。Bが1000から2000に変わり、Aが40のままなら、新しいEAは2040です。領域内の位置40を保ちながら、領域の基準だけを変えられます。ただし、新しい番地の内容が何かは別情報なので、M[2040]の値が未提示ならデータの値までは答えられません。
インデックスでは、先頭番地が1000で、1要素が4バイト、添字0から並ぶ配列の添字3を選ぶ例を考えます。バイト単位の番地なら、先頭からのずれは3×4=12バイトです。レジスタXにこのずれ12が入ると指定されていれば、EA=1000+12=1012になります。
「インデックスレジスタの内容が12」と既に与えられているなら、さらに4を掛けて1048にしないでください。要素番号3からずれを求める問題と、ずれ12を既に与える問題は違います。レジスタの内容が何を表すか、倍率が命令の定義に含まれるかを読み分けます。
CPUごとにアドレスを計算する仕組みは異なるため、実機の命令を学んだ知識から、問題にない倍率を付け足さないことも大切です。まずは「命令中の値+指定レジスタの内容」という基本形と、問題で追加された条件を分けましょう。
16進数と負の変位の注意点
16進数の問題でも、アドレス指定方式の考え方は変わりません。変わるのは加算・減算の表記です。例えばベース指定でB=0x1000、A=0x002Cなら、EA=0x102Cです。ここで0xは16進数を示す印であり、「002C」を10進数として読まないでください。
繰り上がりを確認する例では、B=0x10F0、A=0x0030とします。末尾側のF0+30は0x120となるので、EAは0x1120です。10進数で確認すると0x10F0=4336、0x0030=48で、合計4384=0x1120になります。方式を間違えたのか、16進数の加算を間違えたのかを切り分けられます。
実効アドレスが0x1120で、M[0x1120]=0x003Aと指定されていれば、読み出すデータは0x003Aです。求められた答えを10進数で書く条件なら58に変換します。EAの0x1120を10進数に直す処理と、データの0x003Aを10進数に直す処理は、対象が違うことに注意しましょう。
相対指定の変位は、後ろへ進む正数だけとは限りません。基準PC=1000、変位=-24なら、EA=1000-24=976です。「PCに足す方式」だから変位の絶対値24を加えるのではなく、符号を含む値を加えます。
問題が変位を8ビットの符号付き2の補数と定義し、そのビット列が11111000なら、変位は-8です。符号なしで読むと248ですが、今回はその解釈を使いません。基準PCが1000ならEA=992になります。8ビットという桁数と、符号付きである条件の両方を確認してください。

PCの基準は、計算前に確定させます。例えば命令の先頭番地が1000、命令長が2バイトで、「次の命令の先頭番地を基準にする」と定義されていれば、基準は1002です。変位が6なら分岐先は1008で、変位が-8なら994になります。1000へ変位を加える計算とは答えが変わります。
一方、問題が「計算に使うPCの内容は1000」と明示しているだけなら、その値を使います。そこへ命令長を勝手に足す必要はありません。すでに更新されたPCか、命令先頭から自分で求めるPCかを、条件の書き方で判断します。
具体例として、Zilog公式のZ80 CPUマニュアルのRelative Addressingでは、符号付き変位を次の命令の位置へ加える仕様が説明されています。これはZ80の仕様を確認する資料であり、すべてのCPUの相対指定に同じ命令長や基準を適用するという意味ではありません。
番地の単位がバイトか語かも同じように確認します。1語=4バイトという条件で、命令長が2語なら、バイト番地では8バイト分進みます。語単位の番地なら2だけ進みます。単位が一致しているかを見てから加算し、指定のない語長を推測しないでください。
自作問題で番地と値を確認
最後に、ここまでの判定を自分で試してみましょう。次の練習問題はこの記事の独自問題です。数値は10進数、参照するのは単一の対象データとし、間接指定は1段とします。各問で「実効アドレス」と「対象データ」を別々に考えてから、解答を確認してください。
| 問 | 条件 | 指定方式 |
|---|---|---|
| A | 命令中の値が200、M[200]=600 | 即値 |
| B | A=200、M[200]=600、M[600]=25 | 直接 |
| C | A=200、M[200]=600、M[600]=25 | 間接 |
| D | R3の内容が600、M[600]=25 | レジスタ指定とレジスタ間接を比較 |
| E | A=20、PC=800、B=1200、X=4。M[820]=11、M[1220]=22、M[24]=33 | 相対・ベース・インデックスを比較 |

問Aの対象データは200で、主記憶の実効アドレスは求めません。M[200]=600という情報に引っ張られると直接指定の答えになります。まず、命令中の値をそのまま使うという指定を適用できているか確認しましょう。
問BのEAは200、対象データは600です。M[600]=25は使いません。問CのEAは600、対象データは25です。最初の参照で得た値を番地として使うかどうかが、BとCを分けるところです。
問Dのレジスタ指定では、R3の内容600が対象データです。レジスタ間接ならEA=600、対象データは25です。R3という番号から主記憶3番地を参照する計算になっていないかも見てください。
問Eは、相対ならEA=800+20=820でデータは11、ベースならEA=1200+20=1220でデータは22、インデックスならEA=20+4=24でデータは33です。途中式を「PC+A」「B+A」「A+X」のように名前付きで書くと、レジスタの選択ミスが見つけやすくなります。
この練習で答えが合ったら、数値だけを変えても説明できるか試すと理解を確かめられます。例えば問CでM[200]を700へ変えたら、EAは700へ変わります。そのときM[700]が与えられていなければ、データの値は不明です。元の表の25をそのまま使うことはできません。
逆にM[600]だけを25から30へ変えた場合、問CのEA=600は変わらず、対象データだけが30になります。番地を決める情報と、番地に置かれたデータを変更する情報を分けて考えられれば、単なる公式暗記より一歩進んだ理解になっています。
図問題の復習では、同じことを矢印で試してください。主記憶の内容を読むたびにMを一つ書き、加算する位置ではレジスタ名を書きます。ただし矢印の本数だけで判定せず、線がレジスタ・番地・データのどれを結んでいるかを見ます。図の読み方が変わっても式を再現できる状態を目指しましょう。
基本情報のアドレス指定方式のまとめ
基本情報のアドレス指定方式は、指定値の役割を決める→実効アドレスを求める→必要な場合に内容を読むという順で解きます。即値とレジスタ指定はデータそのものを使い、直接・間接・レジスタ間接は参照経路を、相対・ベース・インデックスは加えるレジスタを確認してください。
解く前の確認は、答えが番地かデータか、数字が何進数か、相対指定の基準PCがどこかの三点です。配列の問題では、レジスタの値が添字なのか既に計算されたずれなのかも確認しましょう。式へ入れる前に条件を整理すると、計算そのものは短くなります。
命令を読み出してから実行する流れも整理したい場合は、基本情報のパイプライン処理とハザードが次の復習につながります。アドレス指定の問題では参照先、パイプラインの問題では工程と時間に着目すると、CPU分野の別々の疑問を整理できます。
この記事の例題を説明できたら、基本情報の過去問アプリで無料演習して、実際の問題文でも番地と値を読み分けてみましょう。まずは答えを見る前に、使った方式と途中式を一行書く練習がおすすめです。


コメント