レジスタ (CPU)
出典: フリー百科事典『ウィキペディア(Wikipedia)』
レジスタは、CPUが内部に保持する少量で高速な記憶装置である。
目次 |
[編集] 概説
デジタル回路において、フリップフロップなどの回路素子を用いてデータを保持する回路の事を一般にレジスタと呼ぶが、CPUの内部にもレジスタは多数存在し、たいへん重要な役割をはたしている。
CPU内部のレジスタは、計算結果を一時的に保持したり、RAMやROMなどのメインメモリを読み書きする際のアドレスを保持したり、CPUや周辺機器の動作状態を保持・変更したりする。CPUの動作とは、極端にいえば、プログラムコードに従ってメインメモリとレジスタの間でデータを移送することだと表現できる。
CPU内部にはたいてい数個から数十個のレジスタが入っており、これらの回路はバス回路や演算回路などと密接に結びついているため、高速に動作する。
CPUの処理能力について述べる際に、よく「○○ビットのCPU」という表現が用いられる事があるが、この際のビット数はCPU内部のレジスタ1個1個の構成ビット数を指す。レジスタの種類によって、同じCPUの中に入っているレジスタでもビット長がまちまちであることがあるが、たいていの場合、演算結果を保持するアキュムレータのビット数がそのCPUの処理ビット数であると考える。
多くのCPUは、メインメモリとのデータのやりとりにもちいるデータバスのビット数と、前述のアキュムレータのビット数とは同じであるが、いくつかのCPUはこれらのビット数が異なる。その場合、データバスのビット数を「外部ビット数」、アキュムレータのビット数を「内部ビット数」と表現する。例えば、モトローラ社のMC68000はデータバスが16ビット、アキュムレータが32ビットだったので、「内部32ビット、外部16ビットCPU」と表現された。
CPUの内部にどのようなレジスタがあるかということは、そのCPUの構造(アーキテクチャ)を示す最も重要な点である。
[編集] レジスタの種類
CPU内部のレジスタには、用途に応じていくつかの種類がある。
[編集] アキュムレータ
演算結果を置いたり、データを一時的に記憶するレジスタである。アキュムレータを持たないCPUは無い。アキュムレータには足し算、引き算などの基本的な演算を行なう回路が付属しており、アキュムレータのデータとデータバス上のデータを演算した結果をアキュムレータに保存することができるようになっている。また、データバスからデータを取り込んだり、データバスにデータを出したりすることができるようになっている。データレジスタと呼ぶこともある。
A, ACCと略される事が多い。
[編集] アドレスレジスタ
メモリをアクセスする場合のアドレスを指定するときに用いるレジスタ。この内容をアドレスバスに出す事により、メインメモリからデータを読み出す。また、CPUによっては、アドレスを計算するための演算回路が付属しており、実効アドレスの計算を行なうことができるようになっていることもある。
[編集] インデックスレジスタ
アドレスレジスタの一種であるが、アドレス計算用の加算回路がついており、メインメモリのアドレスのオフセットを格納するレジスタである。配列データにアクセスするコードが簡単に記述できる。ベースレジスタ、ベースポインタと呼ばれる事もある。
IX,BPなどと略される事がある。
[編集] スタックポインタ
これもアドレスレジスタの一種であるが、CPUの動作状態(すなわちCPU内部レジスタの値)を一時保存する場所のアドレスを保持する目的に用いられる場合、スタックポインタと呼ばれる。スタックポインタは、レジスタの内容をデータバスに送出した後に自動的に値が増加または減少する(次の保存場所を指し示す)ようになっている事が多い。また、逆に自動的に値を減少または増加させてからデータバスの内容をレジスタに取り込む機能もついている。これらの動作は、「ポストインクリメント」「ポストデクリメント」「プリデクリメント」「プリインクリメント」と呼ばれる。
SPと略される事が多い。
[編集] 汎用レジスタ
アキュムレータとしてもアドレスレジスタとしても、どちらにも自由に使えるレジスタ。データの計算をする回路とアドレスの計算をする回路を一緒にしてしまう事ができる上、命令の種類を減らす事ができるため、ほとんどのCPUは汎用レジスタを持っている。また、汎用レジスタを複数個用意しておけば、プログラミングの自由度が格段に増し、特にコンパイラが実行効率の良いオブジェクトコードを生成しやすくなる。RISC系CPUでは全ての汎用レジスタが同等の機能を有している事が多い。そのような設計を「レジスタの直交性が高い」と表現する事がある。なお、CPUの設計においては、計算対象の指定方法がほぼ全ての命令で同じである(オペランドのアドレッシングが命令に依存しない)ことを「命令の直交性が高い」などと表現する事があるが、これはレジスタの直交性とは異なる概念である。
[編集] ページレジスタ、セグメントレジスタ
メモリのアドレス範囲を示すレジスタ。汎用レジスタの設計にすると、アドレスレジスタのビット長は必然的にCPUの処理ビット数になってしまうが、8ビット、16ビットといった少ないビット数のCPUの場合、これではアドレス空間が足りなくなってしまう事が多い。例えば16ビットCPUではアドレス指定も16ビット=64Kバイトまでしかできない事になってしまうが、これは近年のアプリケーションには小さすぎる。このような場合、アドレスレジスタの上位に数ビットから十数ビットを補ってアドレス空間を広げるという事が行なわれる。この上位ビットを保持するレジスタがページレジスタである。セグメントレジスタの場合、その内容を左に数ビットずらしたものとアドレスレジスタの値を足したものが実効アドレスになる。このようにする事により、メモリ空間内で連続的に使用する事のできない部分をなくす事ができる。
セグメントレジスタを持つCPUで最も有名なものは、インテルの8086とその後継CPUである。
[編集] プログラムカウンタ
次に実行するべき命令が格納されているメインメモリ上のアドレスを指し示すレジスタ。命令の読み込みを行なう際にはその内容がアドレスバス上に出力され、また命令を読み込む度に読み取った命令の分だけ値が増加するようになっている。分岐命令は、このプログラムカウンタに値を代入することで実現される。さらに、スタックポインタと組み合わせ、プログラムカウンタの内容をスタックに一次保存した後に新たな値を代入すると、サブルーチンの呼出しを実現する事になる。また、スタックから値を取り出してプログラムカウンタに代入すると、サブルーチンから呼出し元に制御を復帰させる事になる。
PCと略される事が多い。また、インストラクションポインタと呼び、IPと略す事もある。
[編集] ステータスレジスタ
演算結果によって生じた「桁あふれ」やアキュムレータが0であることの状態、あるいは各種のCPUの状態を保持するレジスタである。基本的には、ステータスレジスタは読み出し専用である。しかし、読み出しの時にはステータスレジスタとして働き、書き込みの時には後述するコントロールレジスタとして働くようになっていることも多い。
[編集] コントロールレジスタ
ステータスレジスタで読み出される各種フラグをリセット(解除)したり、CPUを特殊な動作状態にする(動作速度を落として低消費電力状態にするなど)ことを指示するレジスタ。基本的には、コントロールレジスタは書き込み専用であるが、前述のステータスレジスタと共用になっている事も多い。
[編集] ペリフェラルコントロールレジスタ
CPUの周辺機器(プログラマブル・カウンタや割り込み制御、シリアル通信ポートなど)の動作を設定したり、動作状況を読み出したりするためのレジスタである。組み込み機器用に設計されたCPUの場合、多数の周辺機器がCPUチップ内に納められており、ペリフェラルコントロールレジスタだけで数十個になる事も多い。CPUに内蔵されていない周辺機器の場合にもレジスタと呼ぶことが多い。
[編集] 特殊なアーキテクチャ
[編集] レジスタセット
レジスタの値は、CPUの内部状態そのものである。つまり、レジスタの値をそっくりそのままどこかに退避させ、後にそれをそっくり元に戻す事ができれば、CPUの動作を一時中断し、他の作業をさせ、中断前の状態に戻すという事ができることになる。
割り込み処理による高速応答性を要求されるアプリケーションを作る場合や、時分割などによる擬似的なマルチタスクを実現する時には、この動作はきわめて頻繁に行なわれる。この、CPUの動作状態をそっくり保存して他の動作状態に入れ替えるという動作は、コンテキストスイッチと呼ばれる。
一般には、コンテキストスイッチはスタックを用いてレジスタの内容を外部のメインメモリの一定領域上に一次保存することで実現されている。しかし、コンテキストスイッチを高速化するために、主要なレジスタのコピーを保持する別のレジスタ群をCPU内部に用意しておき、それを用いてコンテキストスイッチを行なうという設計になっているCPUもある。つまり、CPU内部のハードウェアにより、一瞬にしてアクセスするレジスタを切り替えてしまう事ができるのである。このようなレジスタ群を「レジスタセット」と呼ぶ。また、切り替えるレジスタ群が1セットしか無い場合、それらのレジスタは「シャドーレジスタ」または「裏レジスタ」と呼ばれる。
レジスタセットを用いたコンテキストスイッチは、処理速度を飛躍的に上げる事ができる画期的な手法であるが、致命的な問題点がある。レジスタを構成する回路は複雑であり、CPUチップ上に多数実装するのが容易ではない。このため、コンテキストスイッチをするタスクの数が多くなるとレジスタセット内に収まらなくなり、役に立たない事になる。
このため、この手法はあまり複雑な処理を行なう事の無い、小規模な組み込みシステムで用いられるだけで、一般的なOSでは用いられていない。
レジスタセットを持ったCPUで最も有名なものは、ザイログ社のZ80であろう。ただし、セットの数は2つだけであり、一般には裏レジスタと呼ばれている。
[編集] ビットの拡張
ソフトウェア資産の有効活用を目的として、16ビットCPUの命令セットをそのまま動作させる事ができる32ビットCPUを開発するというようなことがしばしば行なわれる。
この場合、CPU内部のレジスタのビット長は大きく(たいていの場合2倍に)なっているのだが、互換性を保つために古いCPUの命令コードで動作する場合には下位のビットしか用いないという動作をする。
インテル社の8086系列のCPUは、このように拡張してきた経緯を持つ代表的なCPUである。8086CPUが誕生する前のインテルの8ビットCPU、8080では汎用レジスタを"a","b","c"...と名付けていた。この名残で、8086では汎用レジスタを"ax", "bx", "cx"...と名付けた。(xはextendの意。)ところが、80386で32ビット化したため、レジスタの名前は"eax", "ebx", "ecx"...という名前になった。(eもextendの意。)さらに、AMD社がAMD64で64ビットに拡張した時には、レジスタ名は"rax", "rbx", "rcx"...という名前になった。
[編集] レジスタと高級言語
[編集] レジスタ変数
C言語など、いわゆる高級言語でソフトを記述するとき、計算途中のデータを格納しておく領域は変数と呼ばれる。一般には、コンパイラによって変数にはメインメモリの一領域が割り当てられる。すなわち、「変数の値を読んで計算し、結果を変数に代入する」というコードは、機械語では次のような一連のコードに展開される。
- メモリから値をアキュムレータに取り込む。
- アキュムレータのデータを計算しアキュムレータに入れる
- 計算結果を保持したアキュムレータの内容をメモリに書き出す。
しかし、その変数の値をさらに何度も何度も使って計算を繰り返してゆくようなプログラムの場合、いちいちメモリの読み書きを行なっているのは非常に効率が悪い事になる。
このような時には、レジスタの内容をメモリに書き出す事無く、どんどん使い回すということが行なわれる。特に、近年のCPUはアキュムレータとして使えるレジスタの数が多いため、この手法は処理の高速化に非常に役に立つ。
このように、メインメモリ中ではなく、CPU内のレジスタ上に値が格納される変数の事を「レジスタ変数」と呼ぶ。
近年の高性能なコンパイラは、プログラムの構造を深く考察して、どの変数をレジスタ変数にすれば処理効率があがるかを自動的に判断してくれる。このため、プログラムを書く人がレジスタ変数を気にする事はほとんどない。
しかし、コンパイラの性能があまりよくなかった時代には、プログラムを書く人が明示的に「この変数をレジスタ変数にせよ」と指示していた事があった。C言語にはこの指示のための宣言子である "register"というキーワードが用意されている。
[編集] サブルーチンの引数
サブルーチンを用いたプログラム(世の中のほとんどのプログラムがそうである)では、サブルーチン呼出し時に計算パラメータを与える事が多い。また、サブルーチンが計算結果を元のルーチンに渡すという事も多く行なわれる。サブルーチンに与えるパラメータを引数、サブルーチンから受け取る計算結果を戻り値と呼ぶが、これらをやりとりするには、一般にはメインメモリ上の一定の領域が用いられる。つまり、呼出し元のルーチンは引数をメインメモリ上の決められた場所に書き込んでからサブルーチンに制御を移す。サブルーチンはその決められた場所のデータを読み取って動作を進める、といった具合である。
一般的なプログラムにおいてサブルーチンの呼出しはきわめて多く行なわれる動作であるため、引数や戻り値の引き渡しの処理を高速化する事はプログラムの動作の高速化にたいへん役立つ。
このため、メインメモリのアクセスを割愛するために引数や戻り値はレジスタに格納して受け渡すという事がよく行なわれる。ただし、CPUによってレジスタの数は限られているため、引数の個数が大量になるとこの手法は用いる事ができない。
近年のCPUはこの目的のために多数のアキュムレータを内蔵しているものが多い。また、一部のRISC型CPUでは、もっぱら引数の引き渡しに用いる事を目的とした、スタック動作を内蔵した多数のレジスタ群を用意している事がある。このレジスタ群はレジスタ・ウィンドウと呼ばれる。