アドレッシングモード

アドレッシングモードは、ほとんどの中央処理装置(CPU)設計における命令セットアーキテクチャの一側面です。アドレッシングモードは、そのアーキテクチャにおける機械語命令が各命令のオペランドをどのように識別するかを定義します。アドレッシングモードは、機械命令内またはその他の場所に含まれるレジスタや定数に 保持された情報を用いて、オペランドの実効メモリアドレスを計算する方法を指定します。

コンピュータプログラミングにおいて、アドレッシングモードは主にアセンブリ言語の開発者やコンパイラ開発者にとって重要な概念です。関連する概念としては、任意の命令が任意のアドレッシングモードを使用できるという性質を扱う 直交命令セットを参照してください。

注意点

アドレッシングモードには、一般的に受け入れられている名称はありません。異なる開発者やコンピュータメーカーが、同じアドレッシングモードに異なる名前を付けたり、異なるアドレッシングモードに同じ名前を付けたりすることがあります。さらに、あるアーキテクチャでは単一のアドレッシングモードとして扱われるアドレッシングモードが、別のアーキテクチャでは複数のアドレッシングモードでカバーされる機能を表す場合もあります。例えば、Digital Equipment Corporation (DEC) VAXなどの一部の複合命令セットコンピュータ(CISC) アーキテクチャでは、レジスタやリテラル定数または即値定数を、単なる別のアドレッシングモードとして扱います。一方、IBM System/360およびその後継機種、そしてほとんどの縮小命令セットコンピュータ(RISC) 設計では、この情報が命令内にエンコードされます。そのため、後者のマシンでは、レジスタ間のコピー、リテラル定数のレジスタへのコピー、メモリ位置の内容をレジスタにコピーするための3つの異なる命令コードが存在します。一方、VAXには「MOV」命令が1つしかありません。さらに事態を混乱させるのは、 Microchip Technology PIC マイクロコントローラなどの一部のプロセッサでは、レジスタとメモリを区別しないという点です。

「アドレッシングモード」という用語自体にも、様々な解釈があります。「メモリアドレス計算モード」と「オペランドアクセスモード」のいずれかです。前者の解釈では、メモリからの読み出しやメモリへの書き込みを行わない命令(「リテラルをレジスタに加算」など)は「アドレッシングモード」を持たないとみなされます。後者の解釈は、VAXなどのマシン(オペランドモードビットを用いてレジスタまたはリテラルオペランドを指定する)に適用できます。「実効アドレスをロード」などの命令には前者の解釈のみが適用されます。この命令はオペランド自体ではなく、オペランドのアドレスをロードします。

以下に挙げるアドレッシングモードは、コードアドレッシングとデータアドレッシングに分けられます。ほとんどのコンピュータアーキテクチャはこの区別を維持していますが、(ほぼ)すべてのアドレッシングモードをあらゆるコンテキストで使用できるアーキテクチャも存在します(または存在していました)。

以下に示す命令は、アドレス指定モードを説明するための典型的なものであり、必ずしも特定のコンピュータで使用されるニーモニックを反映しているわけではありません。

IBM 709、RCA 3301などの一部のコンピュータでは、単一のアドレスモードフィールドを持たず、間接アドレス指定とインデックス指定のために別々のフィールドを持っています。 [ 1 ]

アドレッシングモードの数

コンピュータアーキテクチャは、ハードウェアで提供されるアドレッシングモードの数に関して大きく異なります。複雑なアドレッシングモードを排除し、1つまたは少数のより単純なアドレッシングモードのみを使用することには、いくつかの利点があります。ただし、これにはいくつかの追加命令と、場合によっては追加のレジスタが必要になります。[ 2 ] [ 3 ]利用可能なアドレッシングモードが単純なものだけであれば、パイプライン型CPUの設計ははるかに容易になること が証明されています[ 4 ] [ 5 ] [ 6 ]

ほとんどのRISCアーキテクチャは5種類程度のシンプルなアドレッシングモードしか備えていませんが、DEC VAXなどのCISCアーキテクチャは12種類以上のアドレッシングモードを備えており、その中には非常に複雑なものもあります。IBM System/360アーキテクチャは4種類のアドレッシングモードしか備えていませんが、 ESA/390アーキテクチャではさらにいくつかのアドレッシングモードが追加されています。

アドレッシングモードが少数の場合、必要なアドレッシングモードは通常、命令コード内にエンコードされます(例:IBM System/360および後継機種、ほとんどのRISC)。しかし、アドレッシングモードが多数ある場合は、アドレッシングモードを指定するために命令内に特定のフィールドが確保されることがよくあります。DEC VAXでは、ほぼすべての命令で複数のメモリオペランドが許可されていたため、各オペランド指定子の最初の数ビットが、その特定のオペランドのアドレッシングモードを示すために予約されていました。アドレッシングモード指定ビットをオペコード操作ビットから分離することで、直交命令セットが生成されます。

多くのアドレッシングモードを備えたコンピュータであっても、実際のプログラムの測定結果[ 7 ]によると、以下に挙げる単純なアドレッシングモードが、使用されているアドレッシングモードの約90%以上を占めていることが示されています。このような測定のほとんどは、高級言語からコンパイラによって生成されたコードに基づいているため、これはある程度、使用されているコンパイラの限界を反映しています。[ 8 ] [ 7 ] [ 9 ]

有効アドレスをロード

IBM System/360およびその後継機種[ 10 ] 、 Intel x86 [ 11 ]、Motorola 68000シリーズ[ 12 ]などの一部の命令セットアーキテクチャにはロード実効アドレス命令 があります。この命令は、実効オペランドアドレスを計算し、それが参照するメモリにアクセスすることなく、レジスタにロードします。これは、配列要素のアドレスをサブルーチンに渡すときに便利です。また、1つの命令で通常よりも多くの計算を行うための巧妙な方法でもあります。例えば、この命令を「ベース+インデックス+オフセット」というアドレッシングモード(後述)で使用すると、1つの命令で2つのレジスタと定数を加算し、その結果を3つ目のレジスタに格納することができます。[ 13 ]

Motorola 68000シリーズなど、一部の命令セットアーキテクチャには、push effective address命令も存在します。この命令は、実効オペランドアドレスを計算し、レジスタに格納するのではなく、スタックにプッシュします。これにより、関数への引数としてポインタを渡すことが可能です。

コードのシンプルなアドレス指定モード

以下に、コードのいくつかの簡単なアドレッシングモードを示します。命名法はプラットフォームによって異なる場合があります。

絶対的か直接的か

 +----+------------------------------+ |ジャンプ| アドレス | +----+------------------------------+ (有効PCアドレス = アドレス) 

絶対命令アドレスの有効アドレスは、変更されていないアドレス パラメータ自体です。

PC相対

 +----+------------------------------+ |ジャンプ| オフセット | 相対ジャンプ +----+------------------------------+ (有効PCアドレス = 次の命令アドレス + オフセット、オフセットは負の場合もあります) 

PC相対命令アドレスの実効アドレスは、次の命令のアドレスにオフセットパラメータを加算した値です。このオフセットは通常、命令の前後のコードを参照できるように符号付きです。[ 14 ]

これはジャンプ命令との組み合わせで特に有用です。なぜなら、典型的なジャンプは近くの命令へのジャンプだからです(高級言語では、ほとんどのif文やwhile文は比較的短いです)。実際のプログラムを測定したところ、8ビットまたは10ビットのオフセットは、条件付きジャンプの約90%(およそ±128バイトまたは±512バイト)に十分な大きさであることが示唆されています。[ 15 ] 近くにない命令へのジャンプには、他のアドレッシングモードが使用されます。

PC 相対アドレス指定のもう 1 つの利点は、コードが位置に依存しないことです。つまり、アドレスを調整する必要なくメモリ内の任意の場所にロードできます。

間接登録

 +-------+-----+ |jumpVia| reg | +-------+-----+ (有効PCアドレス = レジスタ 'reg'の内容) 

レジスタ間接命令の実効アドレスは、指定されたレジスタ内のアドレスです。例えば、アドレスレジスタA7の内容にアクセスするには、(A7) と指定します。

その効果は、指定されたレジスタ内のアドレスを持つ命令に制御を転送することです。

多くの RISC マシン、および CISC IBM System/360と後継機には、戻りアドレスをアドレス レジスタに配置するサブルーチン呼び出し命令があり、そのサブルーチン呼び出しから戻るにはレジスタ間接アドレッシング モードが使用されます。

コードのシーケンシャルアドレッシングモード

順次実行

 +------+ | nop | 次の命令を実行する +------+ (有効PCアドレス = 次の命令アドレス) 

CPU は、連続した命令を実行した後、すぐに次の命令を実行します。

一部のコンピュータでは、順次実行はアドレス指定モードとは見なされません。

ほとんどのCPUアーキテクチャでは、ほとんどの命令はシーケンシャル命令です。そのため、CPU設計者は、これらのシーケンシャル命令の実行速度を向上させるために、他の命令のパフォーマンスを意図的に犠牲にする機能(分岐命令)を追加することがよくあります。

条件分岐は、条件に応じて 2 つの可能な結果のいずれかを PC にロードします。ほとんどの CPU アーキテクチャでは、「実行される」分岐に対しては別のアドレッシング モードを使用し、「実行されない」分岐に対しては順次実行を使用します。

現代の CPU の多くの機能(命令のプリフェッチ、より複雑なパイプラインアウトオブオーダー実行など) は、各命令が次の命令の開始前に終了するという幻想を維持して、たとえそれが内部的に正確には起こっていなくても、同じ最終結果をもたらします。

このような連続した命令の各「基本ブロック」は、参照の時間的および空間的局所性の両方を示します。

シーケンシャル実行を使用しないCPU

プログラムカウンタを用いたシーケンシャル実行を採用していないCPUは非常に稀である。一部のCPUでは、各命令は常に次の命令のアドレスを指定する。このようなCPUは、指定されたアドレスを保持する命令ポインタを持つが、インクリメントする手段がないため、プログラムカウンタではない。このようなCPUには、IBM 650SECDマシンLibrascope RPC 4000、RTX 32Pなどのドラムメモリ型コンピュータが含まれる。 [ 16 ]

水平マイクロコードで実装されたプロセッサでは、マイクロ命令に次の命令アドレスの上位ビットが含まれる場合があります。

他のコンピューティング アーキテクチャでは、プログラム カウンタのさまざまな代替手段を使用してフォン ノイマン ボトルネックを回避しようと試み、さらに進んでいます。

条件付き実行

一部のコンピュータアーキテクチャには条件付き命令( ARMなど。ただし、64ビットモードではすべての命令に適用されるわけではない)や条件付きロード命令(x86など)があり、条件分岐が不要になり、命令パイプラインのフラッシュを回避できる場合があります。「compare」などの命令は条件コードを設定するために使用され、後続の命令には、その条件コードが遵守されるか無視されるかを判断するためのテストが含まれます。

スキップ

 +------+-----+-----+ |skipEQ| reg1| reg2| reg1=reg2の場合、次の命令をスキップします +------+-----+-----+ (有効PCアドレス = 次の命令アドレス + 1) 

スキップアドレッシングは、固定オフセットを持つ特殊なPC相対アドレッシングモードと考えることができます。[ a ] PC相対アドレッシングと同様に、一部のCPUには、1つのレジスタのみを参照するバージョン(「reg1=0の場合はスキップ」)またはレジスタを参照しないバージョンがあり、ステータスレジスタ内の以前に設定されたビットを暗黙的に参照します。他のCPUには、特定のバイト内の特定のビットを選択してテストするバージョン(「reg12のビット7が0の場合はスキップ」)があります。

他のすべての条件分岐とは異なり、「スキップ」命令では命令パイプラインをフラッシュする必要はありませんが、次の命令を無視する必要がある場合があります。

データのシンプルなアドレス指定モード

以下に、データの簡単なアドレス指定モードをいくつか示します。命名法はプラットフォームによって異なる場合があります。

登録(または直接登録)

 +------+-----+-----+-----+ |マル | reg1| reg2| reg3| reg1 := reg2 * reg3; +------+-----+-----+-----+ 

この「アドレッシング モード」には有効なアドレスがないため、一部のコンピュータではアドレッシング モードとは見なされません。

この例では、すべてのオペランドはレジスタ内にあり、結果もレジスタに格納されます。

ベース+オフセット、そしてバリエーション

これは、「ベースプラス変位」または「切り捨て」と呼ばれることもあります。

 +------+-----+-----+----------------+ | ロード | reg | ベース| オフセット | reg := RAM[ベース + オフセット] +------+-----+-----+----------------+ (有効アドレス = オフセット + 指定されたベースレジスタの内容) 

オフセットがゼロの場合、これはレジスタ間接アドレス指定の例になります。つまり、実効アドレスはベースレジスタの値になります。

多くのRISCマシンでは、レジスタ0は値0に固定されています。レジスタ0をベースレジスタとして使用すると、絶対アドレス指定の例となります。ただし、アクセスできるのはメモリのごく一部だけです。

オフセットは、現在のコンピュータメモリのサイズに比べて小さい場合が多いです。しかし、参照の局所性の原則が適用されます。つまり、短期間でプログラムがアクセスしようとするデータ項目のほとんどは、互いにかなり近い位置にあります。

このアドレッシング モードは、インデックス付き絶対アドレッシング モードと密接に関連しています。

例1:サブルーチン内では、プログラマが主に関心を持つのはパラメータとローカル変数であり、通常は1つのベースレジスタ(フレームポインタ)で十分です。このルーチンがオブジェクト指向言語のクラスメソッドである場合は、現在のオブジェクト(一部の高級言語では thisまたはself )の属性を指す2つ目のベースレジスタが必要です。

例 2 : ベース レジスタに複合型(レコードまたは構造体)のアドレスが含まれている場合、通常、オフセットを使用してそのレコードからフィールドを選択できます。

即時/文字通り

 +------+-----+-----+----------------+ | 加算 | reg1| reg2| 定数 | reg1 := reg2 + 定数; +------+-----+-----+----------------+ 

この「アドレッシング モード」には有効なアドレスがないため、一部のコンピュータではアドレッシング モードとは見なされません。

定数は符号付きまたは符号なしの場合があります。例えば、move.l #$FEEDABBA, D0「FEEDABBA」の16進即値をレジスタD0に移動するなどです。

メモリからオペランドを取得する代わりに、オペランドの値は命令自体の中に保持されます。DEC VAXマシンでは、リテラルオペランドのサイズは6ビット、8ビット、16ビット、または32ビットです。

アンドリュー・タネンバウムは、プログラム内のすべての定数の 98% が 13 ビットに収まることを示しました ( RISC 設計哲学を参照)。

暗黙

 +-----------------+ | キャリービットをクリア | +-----------------+ +-------------------+ | アキュムレータをクリア | +-------------------+ 

暗黙のアドレッシング モード ( x86 アセンブリ言語)とも呼ばれる暗黙のアドレッシング モードでは、ソースまたは宛先 (または場合によっては両方) の有効なアドレスが明示的に指定されません。

オペコードによって、ソース (存在する場合) または宛先の有効アドレス (または場合によっては両方) が示されます。

暗黙的なアドレッシングは、古いコンピュータ(1970年代半ばまで)では非常に一般的でした。そのようなコンピュータには通常、演算を実行できるレジスタが1つだけ、つまりアキュムレータ(累算器)しかありませんでした。このようなアキュムレータマシンは、ほぼすべての命令でそのアキュムレータを暗黙的に参照します。例えば、< a := b + c; > という演算は、< load b; add c; store a; > というシーケンスで実行できます。つまり、ロード先(アキュムレータ)はすべての「ロード」命令と「加算」命令で暗黙的に指定され、ソース(アキュムレータ)はすべての「ストア」命令で暗黙的に指定されます。

その後のコンピュータには、一般に、演算のソースまたは宛先、あるいはその両方として使用できる複数の汎用レジスタまたは RAM ロケーションが用意されていたため、その後のコンピュータでは、演算のソースと宛先を指定するために別のアドレス指定モードが必要になりました。

x86 命令の中には、オペランドまたは結果の 1 つに暗黙のレジスタを使用するものがあります (乗算、除算、条件付きジャンプのカウント)。

一部の命令セット (x86 や AVR など) には、スタック ポインタと呼ばれる特殊用途のレジスタが 1 つあります。このレジスタは、スタックからデータをプッシュまたはポップするときに暗黙的に増分または減分され、ソースまたは宛先の有効アドレスは (暗黙的に) そのスタック ポインタに格納されているアドレスになります。

その他の命令セット ( m68k、ARM、PowerPC など) には、スタック ポインターとして使用できるレジスタが複数あります。そのため、「レジスタ自動増分間接」アドレッシング モードを使用して、スタックからデータをプッシュまたはポップするときに使用するレジスタを指定します。

現在の一部のコンピュータ命令セット ( z/ArchitectureIA-32 / x86-64など) には、以前の設計との下位互換性を維持するために、暗黙的なオペランドを持つ命令がいくつか含まれています。

一部の命令セットでは、ユーザー/システムモードビットや割り込み許可ビットなどを反転する命令は、それらのビットを保持する特殊レジスタを暗黙的に指定します。これにより、Popek法とGoldberg法の仮想化要件を満たすためにこれらの命令をトラップするために必要なハードウェアが簡素化されます。このようなシステムでは、トラップロジックはオペランド(または最終実効アドレス)を参照する必要がなく、オペコードのみを参照します。

一部の命令セットは、すべてのオペランドが常にすべての命令で暗黙的に指定されるように設計されています (ゼロオペランドCPU)。

コードまたはデータのその他のアドレス指定モード

絶対的/直接的

 +------+-----+--------------------------------------+ | ロード | レジスタ | アドレス | +------+-----+--------------------------------------+ (有効アドレス = 命令で指定されたアドレス) 

これには、命令内にかなり大きなアドレスのためのスペースが必要です。x86などの可変長命令を持つCISCマシンでは、この方法が利用できることが多いです。

一部のRISCマシンには、16ビットまたは20ビットの定数をレジスタの上位半分に格納する特別なロード上位リテラル命令があります。この定数は、ベース・プラス・オフセット・アドレッシングモードのベースレジスタとして使用され、下位16ビットまたは12ビットのアドレスを提供します。この組み合わせにより、完全な32ビットアドレスを実現できます。

インデックス付き絶対

 +------+-----+-----+--------------------------------+ | ロード | reg |インデックス| アドレス | +------+-----+-----+--------------------------------+ (有効アドレス = アドレス + 指定されたインデックスレジスタの内容) 

これも、命令内にかなり大きなアドレスのためのスペースを必要とします。アドレスは配列またはベクトルの先頭アドレスであり、インデックスは必要な特定の配列要素を選択することができます。プロセッサは、各配列要素のサイズに合わせてインデックスレジスタをスケーリングする場合があります。

これはベース プラス オフセット アドレッシング モードとほぼ同じですが、この場合のオフセットは任意のメモリ位置をアドレス指定できるほど十分に大きい点が異なります。

例1:サブルーチン内で、プログラマは文字列をローカル定数または静的変数として定義できます。文字列のアドレスは命令内のリテラルアドレスに格納されます。オフセット(ループのこの反復処理で使用する文字列の文字)はインデックスレジスタに格納されます。

例2:プログラマは、複数の大きな配列をグローバル変数またはクラス変数として定義することがあります。配列の先頭は、それを参照する命令のリテラルアドレス(おそらくプログラムのロード時に再配置ローダーによって変更される)に格納されます。オフセット(ループのこの反復処理で配列のどの項目を使用するか)は、インデックスレジスタに格納されます。ループ内の命令は、ループカウンターと複数の配列のオフセットに同じレジスタを再利用することがよくあります。

ベースプラスインデックス

 +------+-----+-----+-----+ | ロード | レジスタ | ベース|インデックス| +------+-----+-----+-----+ (有効アドレス = 指定されたベースレジスタの内容 + 指定されたインデックスレジスタの内容) 

ベースレジスタには配列またはベクトルの開始アドレスが格納され、インデックスレジスタによって必要な配列要素を選択できます。プロセッサは、各配列要素のサイズに合わせてインデックスレジスタのサイズを調整できます。これは、パラメータとして渡された配列の要素にアクセスするために使用できます。

ベース + インデックス + オフセット

 +------+-----+-----+-----+----------------+ | ロード | レジスタ | ベース|インデックス| オフセット | +------+-----+-----+-----+----------------+ (有効アドレス = オフセット + 指定されたベースレジスタの内容 + 指定されたインデックスレジスタの内容) 

ベースレジスタにはレコードの配列またはベクトルの開始アドレスが格納され、インデックスレジスタは必要な特定のレコードを選択し、オフセットレジスタはそのレコード内のフィールドを選択できます。プロセッサは、各配列要素のサイズに合わせてインデックスレジスタをスケーリングできます。

スケール

 +------+-----+-----+-----+ | ロード | レジスタ | ベース|インデックス| +------+-----+-----+-----+ (有効アドレス = 指定されたベースレジスタの内容 + 指定されたインデックスレジスタのスケールされた内容) 

ベース レジスタには配列またはベクトル データ構造の開始アドレスが含まれ、インデックスには必要な特定の配列要素のオフセットが含まれます。

このアドレッシングモードでは、各配列要素のサイズに合わせてインデックスレジスタの値が動的にスケーリングされます。例えば、配列要素がそれぞれ8バイトの倍精度浮動小数点数である場合、インデックスレジスタの値は実効アドレス計算に使用される前に8倍されます。スケール係数は通常2のべき乗に制限されているため、乗算ではなくシフト演算を使用できます。

間接登録

 +------+------+-----+ | ロード | reg1 | ベース| +------+------+-----+ (実効アドレス = ベースレジスタの内容) 

一部のコンピュータでは、これを独自のアドレッシングモードとして採用しています。多くのコンピュータでは、オフセット値が0のベースとオフセットの組み合わせのみを使用します。例えば、(A7)

レジスタ自動インクリメント間接

 +------+-----+-------+ | ロード | reg | ベース | +------+-----+-------+ (実効アドレス = ベースレジスタの内容) 

実効アドレスを決定した後、ベースレジスタの値はアクセスするデータ項目のサイズだけ増加します。例えば、(A7)+ はアドレスレジスタA7の内容にアクセスし、A7のアドレスポインタを1(通常は1ワード)増加させます。ループ内では、このアドレッシングモードを使用して、配列またはベクトルのすべての要素をステップ実行できます。

高級言語では、結果を返す関数は副作用を持たない方がよいとよく考えられます(副作用がないと、プログラムの理解と検証がはるかに容易になります)。このアドレッシングモードには、ベースレジスタが変更されるという副作用があります。後続のメモリアクセスでエラー(ページフォールト、バスエラー、アドレスエラーなど)が発生し、割り込みが発生した場合、命令の再開はより困難になります。なぜなら、1つまたは複数のレジスタを命令開始前の状態に戻す必要がある場合があるからです。

このアドレッシング モードを使用した場合の障害からの回復に関して実装上の問題を抱えたコンピュータ アーキテクチャが少なくとも 3 つあります。

  • DEC PDP-11。1つまたは2つの自動インクリメントレジスタオペランドを持つことができました。[ 17 ] PDP-11/45やPDP-11/70などの一部のモデルには、レジスタへの変更を記録するレジスタがあり、フォールトハンドラがレジスタの変更を元に戻して命令を再実行できるようにしていました。[ 18 ]
  • モトローラ68000シリーズ。1つまたは2つの自動インクリメントレジスタオペランドを持つことができました。[ 19 ] 68010以降のプロセッサは、バスまたはアドレスエラー時にプロセッサの内部状態を保存し、障害から復帰するときにそれを復元することでこの問題を解決しました。[ 20 ] [ 21 ] [ 22 ] [ 23 ]
  • DEC VAX。最大6個の自動インクリメントレジスタオペランドを持つことができる。フォールト発生時にスタックフレームに保存されるプロセッサステータスロングワードの「First Part Done」ビットは、フォールトが発生した命令を最初から再開してはならない場合にセットされ、問題を解決します。[ 24 ]

レジスタ自動デクリメント間接

 +------+-----+-----+ | ロード | reg | ベース| +------+-----+-----+ (有効アドレス = ベースレジスタの新しい内容) 

有効アドレスを決定する前に、ベース レジスタの値は、アクセスされるデータ項目のサイズだけ減分されます。

ループ内では、このアドレッシングモードを使用して、配列またはベクトルのすべての要素を逆方向に処理できます。このモードを前述のアドレッシングモード(自動インクリメント)と組み合わせて使用​​することで、スタックを実装できます。

自動インクリメント アドレッシング モードの副作用に関する説明を参照してください。

間接的または遅延されたメモリ

この記事で言及されているアドレッシングモードはいずれも、間接アドレッシングを示す追加ビットを持つ場合があります。つまり、あるモードで計算されたアドレスは、実際には実効アドレスを含む位置(通常は完全なワード)のアドレスです。一部のマシンでは、間接ワードはインデックス、間接参照、タリー[ b ]、あるいはこれらの組み合わせ を示す場合があります。

間接アドレッシングは、コードにもデータにも使用できます。ポインタ参照ハンドルの実装が大幅に容易になるほか、他の方法ではアドレス指定できないサブルーチンの呼び出しも容易になります。ただし、間接アドレッシングは、追加のメモリアクセスが必要となるため、パフォーマンスの低下を伴います。

初期のミニコンピュータ(例:DEC PDP-8Data General Nova)には、レジスタ数が少なく、直接アドレス指定範囲も8ビットと限られていました。そのため、メモリ間接アドレス指定は、ある程度のメモリ量を参照するほぼ唯一の方法でした。

DEC PDP-11の8つのアドレッシングモードのうち、半分は遅延アドレッシングです。レジスタ遅延 @Rn は、上記で定義したレジスタ間接と同じです。プリデクリメント遅延 @-(Rn)、ポストインクリメント遅延 @(Rn)+、およびインデックス遅延 @nn(Rn) モードは、パラメータのアドレスを見つけるために読み込まれるメモリ内のアドレスを指します。PDP-11の遅延モードは、プログラムカウンタと組み合わせることで、絶対アドレッシングモードとなります。

PC相対

 +------+------+---------+----------------+ | ロード | reg1 | ベース=PC | オフセット | +------+------+---------+----------------+ reg1 := RAM[PC + オフセット] (実効アドレス = PC + オフセット) 

PC相対アドレッシングモードは、プログラムメモリに格納されている値を、現在の命令から少し離れたレジスタにロードするために使用できます。これは、「ベース+オフセット」アドレッシングモードの特殊なケースと見なすことができ、プログラムカウンタ(PC)を「ベースレジスタ」として選択します。

PC相対データ参照をサポートするCPUはいくつかあります。そのようなCPUには以下のものがあります。

x86-64アーキテクチャと64ビットARMv8-Aアーキテクチャ[ 25 ]、PC相対アドレッシングモードを備えています。x86-64では「RIP相対」、ARMv8-Aでは「リテラル」と呼ばれます。Motorola 6809もPC相対アドレッシングモードをサポートしています。

PDP -11アーキテクチャ、VAXアーキテクチャ、および 32 ビットARM アーキテクチャは、レジスタ ファイルに PC を格納することによって PC 相対アドレス指定をサポートします。

IBM z/Architecture には 一般命令拡張機能がアクティブな場合に PC 相対アドレス指定を使用する特定の命令 (例: Load Relative Long) が含まれています。

このアドレッシング モードを使用すると、コンパイラは通常、定数が命令として誤って実行されるのを防ぐために、定数を使用するサブルーチンの直前または直後の リテラル プールに定数を配置します。

このアドレッシング モードは、常にメモリからデータをフェッチするか、メモリにデータを格納し、その後、順番に次の命令を実行します (実効アドレスはデータを指します)。これを、「PC 相対分岐」と混同しないでください。「PC 相対分岐」は、メモリからデータをフェッチしたり、メモリにデータを格納したりするのではなく、指定されたオフセットにある他の命令に分岐します (実効アドレスは実行可能な命令を指します)。

廃止されたアドレス指定モード

ここに挙げたアドレッシングモードは1950年代から1980年代にかけて使用されていたもので、現在のほとんどのコンピュータでは利用できません。このリストは決して完全なものではありません。他にも、2つまたは3つのインデックスレジスタの絶対マイナス論理和など、興味深く独特なアドレッシングモードが数多く使用されていました。[ 26 ] [ 27 ]

多段階メモリ間接

ワードサイズがアドレスよりも大きい場合、メモリ間接アドレッシングで参照されるワード自体に、別のメモリ間接サイクルを示す間接フラグが設定されている可能性があります。このフラグは間接ビットと呼ばれ、結果として得られるポインタはタグ付きポインタです。間接ビットは、それが直接ポインタか間接ポインタかをタグ付けします。間接アドレスのチェーンが自分自身を参照しないように注意する必要があります。もし参照してしまうと、アドレスを解決しようとする際に 無限ループが発生する可能性があります。

IBM 1620Data General NovaHP 2100シリーズはそれぞれ、このような多段階メモリ間接アドレス指定を備えており、このような無限アドレス計算ループに陥る可能性がありました。Novaのメモリ間接アドレス指定モードは、間接スレッドコードの発明に影響を与えました。

18ビットアドレスと36ビットワードを備えたDEC PDP-10コンピュータは、各ステージでインデックスレジスタを使用する可能性のある多段階間接アドレッシングを可能にしました。優先度割り込みシステムは、各アドレスワードのデコード前に照会されました。[ 28 ]そのため、間接アドレスループは、プリエンプティブマルチタスクスケジューラのタイムスライス期限切れハンドラ を含むデバイスサービスルーチンの実行を妨げることはありませんでした。ループ命令は、他の計算処理を必要とするジョブと同様に扱われました。

メモリマップレジスタ

一部のコンピュータでは、主記憶装置やそれらのレジスタを実装するために使用される主メモリではなく、レジスタを参照するアドレスがありました。初期のコンピュータの中には、アドレス範囲の上限にレジスタアドレスがあったものもありました(例:IBM 650[ 29 ] [ c ] 、 IBM 7070[ 30 ] [ e ]) 。しかし、下限ではレジスタアドレスのみを使用し、メモリの最初の8ワードまたは16ワードのみを使用する傾向がありました(例:ICL 1900、DEC PDP-6/PDP-10)。これは、別途「レジスタをレジスタに追加する」命令は必要なく、「メモリをレジスタに追加する」命令だけで済むことを意味しました。

キャッシュ メモリを搭載していなかった PDP-10 の初期モデルの場合、レジスタを格納するためのより高速な回路を提供しながらも、レジスタがメモリ内にあるかのようにアドレス指定できる「高速レジスタ」オプションがインストールされていれば、メモリの最初の数ワードにロードされたタイトな内部ループは、磁気コア メモリ内よりもはるかに高速に実行されました。

DEC PDP-11シリーズの後期モデルでは、レジスタが入出力領域のアドレスにマッピングされましたが、これは主にリモート診断を可能にすることを目的としていました。紛らわしいことに、16ビットレジスタは連続した8ビットバイトアドレスにマッピングされていました。

メモリ間接と自動インクリメント

DEC PDP-8ミニコンピュータには、8つの特別なアドレス(アドレス8から15)がありました。メモリ間接アドレス指定でアクセスすると、これらのアドレスは使用前に自動的にインクリメントされます。[ 31 ]これにより、アキュムレータを使ってアドレスをインクリメントすることなく、ループ内でメモリをステップ実行することが容易になりました。

データジェネラル・ノヴァミニコンピュータには、アドレス16から31までの16個の特別なメモリ位置がありました。[ 32 ]メモリ間接アドレス指定でアクセスすると、16から23は使用前に自動的に増加し、24から31は使用前に自動的に減少します。

ゼロページ

Data General NovaMotorola 6800ファミリー、およびMOS Technology 6502ファミリーのプロセッサは、内部レジスタが非常に少なかった。算術命令と論理命令は、主に内部レジスタではなくメモリ上の値に対して実行された。その結果、多くの命令はメモリ上の2バイト(16ビット)のアドレスを必要とした。これらのプロセッサのオペコードの長さはわずか1バイト(8ビット)であったため、メモリアドレスがコードサイズの大部分を占めることがあった。

これらのプロセッサの設計者は、「ゼロページ」アドレッシングと呼ばれる部分的な対策を講じました。メモリの最初の256バイト($0000~$00FF、いわゆるページ「0」)には、1バイトの絶対アドレスまたはインデックス付きメモリアドレスを使用してアクセスできました。これにより、命令実行時間は1クロックサイクル、命令長は1バイト短縮されました。頻繁に使用されるデータをこの領域に格納することで、プログラムをより小さく、より高速に実行できるようになりました。

その結果、ゼロページはレジスタファイルと同様に使用されるようになりました。しかし、多くのシステムでは、オペレーティングシステムとユーザープログラムによるゼロページメモリ領域の使用率が高まり、空き領域が限られていたため、その使用が制限されていました。

直接ページ

ゼロページアドレスモードは、 WDC 65816CSG 65CE02Motorola 6809など、いくつかの後期型8ビットプロセッサで強化されました。「ダイレクトページ」アドレッシングと呼ばれるこの新しいモードでは、256バイトのゼロページメモリウィンドウをメモリの先頭(オフセットアドレス$0000)からメモリの最初の64KB内の新しい位置に移動する機能が追加されました。

CSG 65CE02では、新しいベースページ(B)レジスタに8ビットのオフセット値を格納することで、メモリの先頭64KB以内の任意の256バイト境界に直接ページを移動できるようになりました。Motorola 6809も、ダイレクトページ(DP)レジスタで同様の操作が可能でした。WDC 65816はさらに進化し、新しいダイレクト(D)レジスタに16ビットのオフセット値を格納することで、メモリの先頭64KB以内の任意の位置に直接ページを移動できるようになりました。

その結果、ゼロ ページ アドレッシング モードのみを備えた従来のプロセッサと比較して、より多くのプログラムが拡張された直接ページ アドレッシング モードを利用できるようになりました。

境界チェック付きのスケールインデックス

これはスケール インデックス アドレッシングに似ていますが、命令に 2 つの追加オペランド (通常は定数) があり、ハードウェアがインデックス値がこれらの境界内にあるかどうかをチェックする点が異なります。

別のバリエーションでは、ベクトル記述子を使用して境界を保持します。これにより、動的に割り当てられた配列を簡単に実装でき、完全な境界チェックも実行できます。

ワード内のビットフィールドへの間接

一部のコンピュータには、ワード内のサブフィールドに対する特別な間接アドレッシング モードがありました。

GE /Honeywell 600 シリーズの文字アドレス指定間接ワードは、 36 ビットワード内で 6 ビットまたは 9 ビットの文字フィールドを指定します。

DEC PDP-10も36ビットで、メモリを固定サイズのビットフィールド、または1ビットから36ビットまでの任意のサイズのバイトのシーケンスとして扱うことができる特別な命令を備えていました。メモリ内の1ワードのシーケンス記述子(「バイトポインタ」と呼ばれる)は、シーケンス内の現在のワードアドレス、ワード内のビット位置、および各バイトのサイズを保持していました。

この記述子を介してバイトをロードおよびストアする命令と、記述子をインクリメントして次のバイトを指す命令が存在した(バイトはワード境界を越えて分割されなかった)。多くのDECソフトウェアは、ワード(プレーンASCII文字)あたり5つの7ビットバイトを使用し、ワードあたり1ビットは未使用であった。C言語の実装では、ワードあたり4つの9ビットバイトを使用する必要があった。これは、C言語の「malloc」関数がintのサイズがcharのサイズの倍数であると想定しているためである。[ 33 ]実際の倍数は、システムに依存するコンパイル時の演算子sizeofによって決定される。

インデックスの次の命令

Elliott 503[ 34 ] Elliott 803[ 34 ] [ 35 ]およびアポロ誘導コンピュータは絶対アドレス指定のみを使用し、インデックスレジスタを持っていなかった。したがって、間接ジャンプ、つまりレジスタを介したジャンプは命令セットでサポートされていなかった。代わりに、現在のメモリワードの内容を次の命令に追加するよう指示することができる。実行される次の命令に小さな値を追加すると、たとえば、 a をJUMP 0a に変更することができJUMP 20、インデックスジャンプの効果を生み出すことができる。命令は実行中に変更され、メモリ内では変更されない、つまり自己変更コードではないことに注意する。次の命令に追加される値が十分に大きい場合は、アドレスだけでなく、またはその代わりに、その命令のオペコードを変更する可能性がある。

用語集

間接的
ポインタまたはアドレスを通じて参照されるデータ。
すぐに
命令またはコマンド リストに直接埋め込まれたデータ。
索引
動的オフセット。通常はインデックス レジスタに保持され、オブジェクト サイズによってスケーリングされる可能性があります。
オフセット
アドレスに追加される即値。たとえば、C プログラミング言語の構造体フィールド アクセスに相当します。
相対的
別のアドレスを基準にして形成されたアドレス。
増加後の投稿
スタック ポップ操作に使用される、 C プログラミング言語*p++に似た、データの前のアドレスのステップ実行。
事前減分
スタック プッシュ操作に使用される、 C プログラミング言語*--pと同様に、使用前にアドレスを減分します。

参照

注記

  1. ^ワード指向マシンではほとんどの場合 NSI+1 だけですが、たとえばIBM 7090の比較アキュムレータおよびスキップ (CAS) はNSI+1 または NSI+2 にスキップできます。
  2. ^増加または減少のいずれか。
  3. ^ 650用コンデンサー保管ユニット:
    8000 コンソールスイッチ
    8001 ディストリビューター
    8002 下部アキュムレータ
    8003 上部アキュムレータ
  4. ^ a bコンソールからのみ有効
  5. ^ 5Kまたは10K 7070の場合
    00xx インデックスレジスタ xx
    9991 アキュムレータ 1
    9992 アキュムレータ 2
    9993 アキュムレーター 3
    9995 プログラムレジスタ[ d ]
    9999 命令カウンタ[ d ]

参考文献

  1. ^システムリファレンスマニュアル - RCA 3301 REALCOM EDP (PDF) . RCA . 1967年9月. 94-16-000-1 . 2023年12月21日閲覧
  2. ^ F. Chow; S. Correll; M. Himelstein; E. Killian; L. Weber (1987). 「アドレッシングモードは何種類あれば十分か?」 ACM SIGARCH Computer Architecture News . 15 (5): 117– 121. doi : 10.1145/36177.36193 .
  3. ^ John L. HennessyMark A. Horowitz (1986). 「MIPS-X-MPプロジェクトの概要」(PDF) . ... MIPS-Xは、ベースレジスタとオフセットという単一のアドレッシングモードを使用します。このシンプルなアドレッシングモードにより、実効アドレスの計算を非常に早い段階で開始できます。
  4. ^ Jon Squire博士。「講義19、データ転送のパイプライン化」。CS411選定講義ノート
  5. ^ 「高性能コンピューティング、第11回授業ノート(2000年9月15日および20日) - パイプライン」2013年12月27日時点のオリジナルよりアーカイブ。 2014年2月8日閲覧
  6. ^ジョン・ポール・シェン、ミッコ・H・リパスティ (2004).最新のプロセッサ設計マグロウヒルプロフェッショナルISBN 9780070570641
  7. ^ a b John L. Hennessy、David A. Patterson (2002-05-29).コンピュータアーキテクチャ:定量的アプローチ. Elsevier. p. 104. ISBN 9780080502526C54xにはレジスタアクセスを除いて17種類のデータアドレッシングモードがありますが、MIPSに見られる4種類のモードが全体の70%を占めています。一部のRISCアーキテクチャに見られる自動インクリメントと自動デクリメントは、残りの25%を占めています。このデータは、アセンブリ言語で記述された54個のDSPルーチンからなるC言語呼び出し可能ライブラリの静的命令の測定から収集されました。
  8. ^ソフィエンヌ・タハール博士。「命令セットの原則:アドレッシングモードの使用法(概要)」(PDF) 。 2011年9月30日時点のオリジナル(PDF)からアーカイブ。3つのプログラムをすべてのアドレスモード(VAX)でマシン上で測定...75%の変位と即値
  9. ^ Ali-Reza Adl-Tabatabai、Geoff Langdale、Steven Lucco、Robert Wahbe (1995). 「効率的で言語非依存なモバイルプログラム」 . ACM SIGPLAN 1996 プログラミング言語の設計と実装に関する会議論文集 - PLDI '96 . pp.  127– 136. doi : 10.1145/231379.231402 . ISBN 0897917952. S2CID  2534344 .実行されたすべての命令の 79% は、RISC 命令に置き換えるか、基本ブロック命令の組み合わせのみを使用して RISC 命令に合成できます。
  10. ^ 「ロードアドレス」(PDF) . z/Architecture - Principles of Operation(PDF)(第14版). IBM . 2022年5月. p. 7-269. SA22-7832-13 . 2025年5月30日閲覧
  11. ^ "7.3.16.1 アドレス計算命令" (PDF) . Intel® 64 および IA-32 アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル (第1巻、第2A巻、第2B巻、第2C巻、第2D巻、第3A巻、第3B巻、第3C巻、第3D巻、第4巻) (PDF) . 第1巻、Intel Corporation . 2017年7月、p. 7-23 . 2025年6月23日閲覧. LEA (ロード実効アドレス) 命令は、ソースオペランドのメモリ内実効アドレス (セグメント内オフセット) を計算し、汎用レジスタに格納します。この命令は、プロセッサーのあらゆるアドレッシングモードを解釈し、必要に応じてインデックス付けやスケーリングを実行できます。特に、文字列命令の実行前に ESI レジスタまたは EDI レジスタを初期化する場合や、XLAT 命令の実行前に EBX レジスタを初期化する場合に便利です。
  12. ^ 「セクション4 整数命令」(PDF) . M68000ファミリ - プログラマーズ・リファレンス・マニュアル - (CPU32命令を含む)(PDF) . Motorola . 1992年. p.  4-110 . 2025年6月23日閲覧
  13. ^ 「命令使用例」(PDF) . IBM System/360 Principles of Operation(PDF) . IBM. 1968年9月. p.  135. A22-6821-7 . 2019年7月12日閲覧
  14. ^ マックス・マックスフィールド. 「4ビットコンピュータの構築:アセンブリ言語とアセンブラ」 . 「アドレッシングモード」セクション. 2019年.
  15. ^ Kong, Shing; Patterson, David (1995). 「命令セット設計」スライド27.
  16. ^ Koopman, Philip (1989). 「RTX 32Pのアーキテクチャ」 . Stack Computers .
  17. ^ PDP-11アーキテクチャハンドブック(PDF) . Digital Equipment Corporation . 1973.
  18. ^ PDP-11/45プロセッサハンドブック(PDF) . Digital Equipment Corporation . 1973年. pp.  150– 153.
  19. ^ M68000ファミリープログラマーズリファレンスマニュアル(PDF) . Motorola . 1992.
  20. ^ MC68010/MC68012 16/32ビット仮想メモリマイクロプロセッサ(PDF) . Motorola . 1985年5月. pp.  5-12 – 5-15 .
  21. ^ MC68020 32ビットマイクロプロセッサ ユーザーズマニュアル(PDF) . Prentice-Hall . 1984年 . pp.  6-9 – 6-10 . ISBN 0-13-541418-0
  22. ^ MC68030 拡張32ビットマイクロプロセッサ ユーザーズマニュアル(PDF) (第3版). Prentice-Hall . 1990. pp.  8-7 – 8-8 . ISBN 0-13-566423-3
  23. ^ MC68040 32ビットマイクロプロセッサ ユーザーズマニュアル(PDF) (第3版). Motorola . 1989. pp.  9-8 – 9-9 .
  24. ^ VAXアーキテクチャリファレンスマニュアル(PDF) . Digital Equipment Corporation . 1987年. p. 21. ISBN 0-932376-86-X
  25. ^ 「ARMv8 64ビットアーキテクチャ入門」 UICアカデミーquequero.org2014年4月9日。
  26. ^ 704電子データ処理マシン操作マニュアル(PDF) . IBM . 1955年. pp.  10– 11.
  27. ^リファレンス・マニュアル IBM 7090 データ処理システム(PDF) . IBM. 1962年. pp.  9– 10.
  28. ^ DEC-10-HMAA-D: PDP-10 KA10 中央処理装置メンテナンスマニュアル(PDF) (第1刷).マサチューセッツ州メイナード: Digital Equipment Corporation . 1968年12月. pp.  2– 11. 2021年5月15日閲覧.図2-9: 実効アドレス計算: test "PI RQ ?"
  29. ^ 「ストレージ」(PDF) . 650磁気ドラムデータ処理装置 - 操作マニュアル(PDF) . 1955年6月. p.  9. 22-6060-2 . 2022年3月14日閲覧
  30. ^ 「コアストレージとレジスタアドレス」(PDF) .リファレンスマニュアル - IBM 7070データ処理システム(PDF) . 1960年1月 . p. 252. A22-7003-0 . 2022年3月14日閲覧
  31. ^ Jones, Douglas, PDP-8のリファレンスマニュアル、 2013年7月1日閲覧。
  32. ^ Friend, Carl, Data General NOVA命令セット概要、 2013年7月1日閲覧。
  33. ^「Cリファレンス: 関数 malloc()」
  34. ^ a bデイブ・ブルックス「いくつかの古いコンピューター」
  35. ^ビル・パービス。「エリオット803Bハードウェアの詳細」