クレア工房 | 電子工作 | PIC32

PIC32のコアとなるレジスタ

コアとなるレジスタの説明は本来はPIC32固有の事項ではありません。 PIC32が採用するMIPS M4Kコアの話になります。 PIC32でgccを使う場合はスタートアップを自前で記述しますので、 一定程度はどうしてもアセンブリ言語を頼ります。 このため、レジスタに関する知識が必要になります。

原則

CPUのレジスタ

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 デバッグ機能ソフトウェアが自由に使用できる汎用レジスタです。

MIPS16e

即値をとる分岐命令ではMIPS32とMIPS16eの間を切り替えて遷移するための専用の命令が用意されています。 オペランドとなるアドレス値で切り替えているわけではありません。 これは即値がワードアドレスで示されるという、命令語の書式からくる理由によります。

割り込みハンドラと例外ハンドラについてはMIPS32命令モードで開始することしかできません。 MIPS16eの命令体系ではコプロセッサ0にアクセスすることはできません。 割り込みのエントリーではコプロセッサ0にアクセスしなければならないので、 MIPS32モードに制限されることは妥当な制限であると言えるでしょう。


This is copyrighted material. all rights reserved.