コンピュータのCPUのインデックスレジスタは、プログラムの実行中にオペランドアドレスを指すために使用されるプロセッサ レジスタ(または割り当てられたメモリ位置) [ 1 ]です。文字列や配列を順に処理するのに役立ちます。また、ループの反復回数やカウンタを保持するためにも使用できます。一部のアーキテクチャでは、メモリ ブロックの読み書きに使用されます。アーキテクチャによっては、専用のインデックス レジスタまたは汎用レジスタになる場合があります。[ 2 ]一部の命令セットでは、複数のインデックス レジスタを使用できます。その場合、追加の命令フィールドでどのインデックス レジスタを使用するかを指定できます。[ 3 ]
一般的に、インデックス レジスタの内容は、(命令自体の一部であるか、別のレジスタに保持されている)即値アドレスに加算(場合によっては減算)され、実際のデータ(オペランド)の「実効」アドレスが形成されます。通常、インデックス レジスタをテストするための特別な命令が用意されており、テストが失敗した場合は、インデックス レジスタを即値定数だけインクリメントし、通常はループの開始点に分岐します。通常、複数のインデックス レジスタを指定できる命令では内容を加算しますが、IBM には内容を OR で結合するコンピュータのシリーズがありました。[ 4 ]
インデックスレジスタは、ベクトル/配列演算や、商用データ処理におけるレコード内のフィールド間の移動に有用であることが証明されています。どちらの用途においても、インデックスレジスタは使用メモリ量を大幅に削減し、実行速度を向上させます。
間接アドレッシングの形式を持たない初期のコンピュータでは、配列操作は命令アドレスを変更することによって実行されなければならず、そのためにはいくつかの追加のプログラム手順が必要となり、コンピュータのメモリをより多く消費しました[ 5 ] 。これは、初期のコンピュータ設備(および20年後の初期のマイクロコンピュータ)では貴重なリソースでした。
インデックス レジスタは、初期のイギリスのコンピュータでは一般的に B ラインと呼ばれ、一部のマシンでは B レジスタ、他のマシンではX レジスタ[ a ]と呼ばれていましたが、1949 年にイギリスのManchester Mark 1コンピュータで初めて使用されました。一般的に、インデックス レジスタは、コンピュータ技術の第 2 世代(おおよそ 1954 年~ 1966 年) に標準装備されました。IBM 700/7000メインフレームシリーズのほとんどのマシン[ b ]には、1954 年のIBM 704からインデックス レジスタが搭載されていましたが、 IBM 650やIBM 1401などの小型マシンではオプションでした。
インデックスレジスタを備えた初期の「小型マシン」としては、 1960年頃のAN/USQ-17や、1960年代初頭のサイエンティフィック・データ・システムズ社のリアルタイムコンピュータ9シリーズなどが挙げられる。
1962年製のUNIVAC 1107には15個のXレジスタがあり、そのうち4個はAレジスタも兼ねていた。
1964年製のGE-635には8つの専用Xレジスタが搭載されていますが、命令カウンタ、またはAレジスタもしくはQレジスタの半分によるインデックス指定も可能です。
1964 年に導入されたDigital Equipment Corporation (DEC) PDP-6と、同じく1964 年に発表されたIBM System/360には、専用のインデックス レジスタは含まれていません。代わりに、数値またはアドレスのいずれかを格納できる汎用レジスタ(PDP-6 では「アキュムレータ」と呼ばれます) があります。オペランドのメモリ アドレスは、PDP-6 では汎用レジスタの内容と 18 ビット オフセットの合計であり、System/360 では 2 つの汎用レジスタの内容と 12 ビット オフセットの合計です。[ 6 ] [ 7 ] PDP-6 の後継機種である PDP-10 ライン、およびSystem / 360 の後継機種である IBM System/370 とそれ以降の互換性のある機種 (現在のz/Architectureを含む) も同様に動作します。
1969 年のデータ ゼネラル Novaとその後継機Eclipse、および 1970 年 DEC PDP-11ミニコンピュータも、Eclipse MVやVAX 32 ビットスーパーミニコンピュータの後継機のようにアキュムレータとインデックス レジスタが別々ではなく、汎用レジスタ (Nova と Eclipse では「アキュムレータ」と呼ばれた) を提供していた。PDP-11 と VAX では、オペランドのメモリ アドレスを計算する際にどのレジスタでも使用できたが、Nova、Eclipse、Eclipse MV ではレジスタ 2 と 3 しか使用できなかった。[ 8 ] [ 9 ] [ 10 ]
1971年製のCDC STAR-100は、 256個の64ビットレジスタからなるレジスタファイルを持ち、そのうち9個は予約済みである。ほとんどのコンピュータとは異なり、STAR-100の命令にはレジスタフィールドとオペランドフィールドしかないため、レジスタは従来のインデックスレジスタというよりはポインタレジスタとして機能する。
1972年のIntel 8008はレジスタペアによる間接アドレッシングを可能にしたが、真のインデックスレジスタを備えた最初のマイクロプロセッサは1974年のMotorola 6800だったようだ。
1975年当時、8ビットMOSテクノロジー6502プロセッサには「X」と「Y」という2つのインデックスレジスタがありました。[ 11 ]
1978年に登場した最初のx86プロセッサであるIntel 8086には、「汎用」と呼ばれる8つの16ビットレジスタがあり、ほとんどの演算において整数データレジスタとして使用できた。 4つのレジスタ、「SI」(ソースインデックス)、「DI」(宛先インデックス)、「BX」(ベース)、および「BP」(ベースポインタ)は、オペランドのメモリ アドレスを計算する際にも使用できます。これは、これらのレジスタのいずれかと変位の合計、または「BX」または「BP」のいずれか、または「SI」または「DI」のいずれかと変位の合計です。[ 12 ] 1979年のIntel 8088、および16ビットの後継機であるIntel 80186、Intel 80188、Intel 80286は同じように動作します。1985年、これらのプロセッサの32ビット後継機であるi386は、x86アーキテクチャのIA-32 32ビットバージョンを導入し、8つの16ビットレジスタを32ビットに拡張し、レジスタ名の先頭に「E」を追加しました。IA-32では、オペランドは、8 つのレジスタのうちの 1 つ、7 つのレジスタのうちの 1 つ (スタック ポインタはここでは 2 番目のレジスタとして許可されていません) に 1、2、4、または 8 を乗じたもの、および変位の合計です。[ 13 ] : 3-11–3-12、3-22–3-23 2003年に最初のモデルがリリースされた Advanced Micro Devices Opteron は、x86 命令セットの 64 ビット バージョンである x86-64 を導入しました。x86-64では、汎用レジスタが 64 ビットに拡張され、8 つの汎用レジスタが追加されました。オペランドのメモリ アドレスは、16 個のレジスタのうちの 2 つと変位の合計です。[ 14 ] [ 13 ] : 3–12、3–24
1980年代と1990年代に導入されたRISC( Reduced Instruction Set Computing)命令セットはすべて、数値またはアドレス値を格納できる汎用レジスタを提供します。これらの命令セットのほとんどには、オペランドアドレスを計算するために使用できる32個の汎用レジスタ(一部の命令セットでは、これらのレジスタの1つの値がゼロに固定されています)があり、専用のインデックスレジスタはありませんでした。1985年に初めて開発されたARMアーキテクチャの32ビット版では、「汎用レジスタ」として指定された16個のレジスタがありますが、そのうち13個だけがすべての用途に使用でき、レジスタR15にはプログラムカウンタが格納されます。ロード命令またはストア命令のメモリ アドレスは、16個のレジスタのいずれかと、R15を除く他のレジスタの変位または別のレジスタの合計です(スケーリングのために左にシフトされる場合があります)。[ 15 ] ARMアーキテクチャの64ビット版では、31個の64ビット汎用レジスタに加えて、スタックポインタとゼロレジスタがあります。ロード命令またはストア命令のメモリアドレスは、31個のレジスタのいずれかと、ディスプレイスメントまたは別のレジスタのいずれかの合計です。[ 16 ]
以下は、4バイトワードからなる100個の要素の配列を合計する、アセンブリ言語の擬似コードにおけるインデックスレジスタの使用例です。
クリアアキュムレータ Load_index 400,index2 //配列サイズの4倍をインデックスレジスタ2(index2)にロードします loop_start : Add_word_to_accumulator array_start,index2 //アドレス(array_start + index2)にあるワードをアキュムレータに追加します Branch_and_decrement_if_index_not_zero loop_start,4,index2 //インデックスレジスタがゼロになるまで4ずつ減らすループ