コアとなるレジスタの説明は本来はPIC32固有の事項ではありません。 PIC32が採用するMIPS M4Kコアの話になります。 PIC32でgccを使う場合はスタートアップを自前で記述しますので、 一定程度はどうしてもアセンブリ言語を頼ります。 このため、レジスタに関する知識が必要になります。
MIPS32は32本のレジスタ空間と、 ゼロレジスタ1本を除いた31本の汎用レジスタを持ちます。 いくつかはコンパイラの呼び出し規約において用途が明確に予約されています。
レジスタ | シンボル | 説明 |
---|---|---|
r0 | zero | ゼロレジスタ。 読むとゼロが返され、書き込むと値が捨てられる、キッチンシンクなレジスタです。 ハードウェアの動作によって常にゼロが強制されます。 |
r1 | at | アセンブラ・テンポラリ・レジスタ。 アセンブラが一時的な用途で勝手に使用するレジスタです。 ユーザが記述するプログラムからは通常は明示的には使用しませんが、 アセンブラが勝手に使うレジスタであるという性質上、 割り込みのエントリー等では明示的に保存と復帰をしなければなりません。 |
r2, r3 | v0, v1 | 返り値を示すためのレジスタ。 コンパイラの規約でしかないため、アセンブリで記述する場合は単なる汎用レジスタです。 |
r4, r5, r6, r7 | a0, a1, a2, a3 | 引数レジスタ。 コンパイラの規約でしかないため、アセンブリで記述する場合は単なる汎用レジスタです。 |
r8, r9, r10, r11, r12, r13, r14, r15 | t0, t1, t2, t3, t4, t5, t6, t7 | 関数呼び出し時に呼び出された側で破壊されるかも知れない一時レジスタ。 コンパイラの規約でしかないため、アセンブリで記述する場合は単なる汎用レジスタです。 |
r16, r17, r18, r19, r20, r21, r22, r23 | s0, s1, s2, s3, s4, s5, s6, s7 | 関数呼び出し時において呼び出された側で保存される一時レジスタ。 コンパイラの規約でしかないため、アセンブリで記述する場合は単なる汎用レジスタです。 |
r24, r25 | t8, t9 | 関数呼び出し時に呼び出された側によって破壊されるかも知れない一時レジスタ。 コンパイラの規約でしかないため、アセンブリで記述する場合は単なる汎用レジスタです。 |
r26, r27 | k0, k1 | 割り込み発生時に破壊することが許された一時レジスタ。 ユーザプログラムから見ていつ破壊されるか予測が付かないため、 ユーザプログラムから利用することはできません。 割り込みハンドラや例外ハンドラがエントリー作業用に使用するレジスタです。 割り込みハンドラの中においても、再帰的な割り込みを許す場合は、 その範囲において使用することはできません。 |
r28 | gp | グローバルポインタ。 ユーザプログラムの大域変数の基礎アドレスを指し示しておき、 そこからのオフセットでアクセスできるようにするためのレジスタです。 MIPS32の命令体系はx86と異なりフルレンジの即値アドレッシング能力を持たないこと、 さらに命令ポインタ相対によるアドレッシングもできないことから、 再配置可能なプログラムを実現するために必要なレジスタとなっています。 通常、グローバルポインタは64KBある指示可能な空間の中央を指すように指定されます。 中央である理由はオフセット可能な範囲の値が符号付きだからです。 |
r29 | sp | スタックポインタ。 コンパイラの規約でしかありませんので、ハードウェア的には単なる汎用レジスタです。 スタックはソフトウェアで実現しなければなりません。 |
r30 | fp | フレームポインタ。 コンパイラの規約でしかありませんので、ハードウェア的には単なる汎用レジスタです。 スタックに変数領域を予約しないのであれば単なる作業用レジスタとして扱うことができます。 |
r31 | ra | リターンアドレス。 jal等の命令による関数呼び出しにおいて、ハードウェアが戻り先アドレスを格納します。 呼び出された関数は自らの責任でこのレジスタを保存し、リターンしなければなりません。 |
x86のようなフラグレジスタはありません。 フラグを使用せず、単一命令内で比較と分岐が完結するように設計されています。 複雑な比較を実行する必要がある場合は、 汎用レジスタから選んでフラグ代用レジスタとして運用することになります。 MIPS16e拡張では命令エンコードの制限からフラグレジスタの概念がありますが、 これも汎用レジスタから取られます。
MIPS CPUそれ自身は割り込みや例外処理などの制御をしません。 制御に関する動作は、拡張機能であるコプロセッサ0に委ねられています。 この拡張機能は、事実上、CPUコアと一体を成すものとして扱われます。
コプロセッサ0のレジスタは特権命令によってしか読み書きすることはできません。 最初は教育用プロセッサ設計ということで簡略化されていたものが、 実用上の理由で命令の追加となった部分があります。 割り込みの禁止操作は本来はコプロセッサのレジスタ操作で実現するものとされていましたが、 後日になって専用の命令が追加されています。
Number | Select | レジスタ | 記事 |
---|---|---|---|
0-6 | N/A | Reserved | M4Kコアでは扱いません。 |
7 | 0 | HWREna | ハードウェアを操作する命令を許可するためのレジスタです。 何に使うのか良くわかりませんでした。 |
8 | 0 | BadVAddr | アドレスエラーが発生した時に、 その例外を引き起こした仮想アドレスを格納し報告するレジスタです。 バスエラーはアドレスエラーではないのでこのレジスタは関知しません。 |
9 | 0 | Count | プロセッサのクロックを数えているレジスタです。 必要であれば書き込むことができます。 デバッグ例外で割り込んだときにカウンタを増分するかどうかを制御するレジスタが別途存在します。 |
10 | N/A | Reserved | M4Kコアでは扱いません。 |
11 | 0 | Compare | タイマー割り込みを制御します。 古にはコンテキスト切り替えを行うためのタイマーを構成するものでしたので、 OS学習のためにタイマーがCPUに取り込まれています。 このレジスタに値を書き込むとタイマ割り込みがクリアされます。 |
12 | 0 | Status |
プロセッサの状態を管理します。
このレジスタ番号には他のレジスタが多重されています。
|
12 | 1 | IntCtl | 割り込みを管理します。 割り込みテーブルの間隔を制御するビットがここにあります。 |
12 | 2 | SRSCtl | シャドウセットと呼ばれるレジスタバンクを管理します。 レジスタバンクの数を報告するビットがあります。 |
12 | 3 | SRSMap | シャドウセットと呼ばれるレジスタバンクを管理します。 割り込み発生時における割り込み番号とレジスタバンク番号を紐付けます。 ベクタ割り込みモードを選択した場合にのみ意味があります。 |
13 | 0 | Cause | 最後に発生した例外の理由を報告するレジスタです。 |
14 | 0 | EPC | 最後に発生した例外において、例外を発生した命令を指すポインタ(PC)を保存しているレジスタです。 |
15 | 0 | PRId | プロセッサを識別する情報を保持しているレジスタです。 |
15 | 1 | EBase | 例外が発生したときのベクタテーブルのベースアドレスを指すポインタであると同時に、 マルチプロセッサシステムにおいてプロセッサ番号を報告するレジスタです。 レジスタのビット構成の都合により、 例外ベクタテーブルは4KB境界に整列されていなければなりません。 |
16 | 0 | Config | プロセッサに対する設定を保持しているレジスタです。 |
16 | 1 | Config1 | プロセッサに対する設定を保持しているレジスタです。 |
16 | 2 | Config2 | プロセッサに対する設定を保持しているレジスタです。 |
16 | 3 | Config3 | プロセッサに対する設定を保持しているレジスタです。 |
17-22 | N/A | Reserved | M4Kコアでは扱いません。 |
23 | 0 | Debug | デバッグ機能を司るレジスタです。 |
24 | 0 | DEPC | デバッグ例外が発生した時点における命令カウンタを保持しているレジスタです。 |
25-29 | N/A | Reserved | M4Kコアでは扱いません。 |
30 | 0 | ErrorEPC | エラーが発生した時点における命令カウンタを保持しているレジスタです。 |
31 | 0 | DeSAVE | デバッグ機能ソフトウェアが自由に使用できる汎用レジスタです。 |
即値をとる分岐命令ではMIPS32とMIPS16eの間を切り替えて遷移するための専用の命令が用意されています。 オペランドとなるアドレス値で切り替えているわけではありません。 これは即値がワードアドレスで示されるという、命令語の書式からくる理由によります。
割り込みハンドラと例外ハンドラについてはMIPS32命令モードで開始することしかできません。 MIPS16eの命令体系ではコプロセッサ0にアクセスすることはできません。 割り込みのエントリーではコプロセッサ0にアクセスしなければならないので、 MIPS32モードに制限されることは妥当な制限であると言えるでしょう。