CCMBソース読解の道しるべ

戻る



・レジスタ割り当ての規則

 CCMBは(そのスーパーセットであるCMBもですが)、次のようにきわめてアクセス頻度の高いインタプリタ用のグローバル変数を常時レジスタに割り当てています。Cなどのコンパイラで作るとこのような「グローバル変数を常時レジスタに割り付ける」なんてことはやってくれないと思います。

レジスタ

エイリアス

機 能

R11

LINEP

現在実行中の行の先頭を指すポインタ

R12

EXEP

現在まさに解釈・実行中の文字を指すポインタ

R13


2バイト、4バイトの即値ロード用

R14


構文チェック用ソフトウエアスタックポインタ



 私はこれまで、Z80、80x86リアルモード、H8のBASICを作ってきましたが、SHになって汎用レジスタが15個になって急に自由度が増したように感じました(H8はERnを1個の汎用レジスタと考えると結局7個で、8086等と比べてあまり増えた感じはしませんでした)。それらのCPUではLINEP、EXEPのレジスタへの常時割り当ては行っていません。H8版では、ソフトウエアスタックポインタのみER6に常時割り付けしています。



 GBRも、IOアクセス時などのごくわずかなケースを除いてほとんど常にBASICインタプリタのワークエリアの先頭を指しています。これによりインタプリタは非常に高速に動作します。

 また、R3にはよく実行ポインタEXEPがコピーされます。EXEPをR3にコピーしてそれが指しているものが何であるか調べ、取り込むべきものであった場合そのサイズぶん進んだR3をEXEPに書き戻し、そうでなければEXEPはそのままでR3の内容を破棄する、という処理がそこかしこにあります。

 それ以外にもR3は何らかのデータを指すポインタに使われることが多く、R2は関数などへのデータの受け渡しに使われることが多いです。それは一番最初に作ったZ80版の名残でHL、DEレジスタがやっていたことをSH版ではそれぞれR3、R2に割り振っているからです。


・ラベル命名規則

 必ずしも100%のっとっていないところもありますが、大体次のようなルールで名前をつけていますので、覚えておくと概要がつかみやすくなります。

● Qで始まるラベル名のルーチンは「□△であるか否か」を判定し、□△であると判断すればSRのTビットをセットしてリターン、そうでなければTビットをクリヤしてリターンする。

なお、私はサブルーチンの戻り値が真か偽か、あるいは成功か失敗かといったブール値の場合、SRのTビットで返す、という手法を多用しています。これだとたった1ビットの情報のために貴重な汎用レジスタを1つ潰す必要がありませんし、受け取った側は即条件分岐できます。(これもZ80版ではキャリーフラグで渡していた名残))
Cなどのコンパイラでプログラムを組むと汎用レジスタにH'00000000あるいはH'00000001を返す、というコードになってしまうケースが多く、受け取った側はTSTやCMP/EQで判断しなければいけません。



● Xで始まるラベル名のルーチンは文、関数、演算子などの実行ルーチン本体である

● 何かを処理するルーチンの中で、処理に成功すれば□△Eというラベルに分岐してそのルーチンを抜ける(正常終了)。失敗した場合は□△Nというラベルに分岐してルーチンを抜ける(否定的終了)。SCANルーチンのSCANEラベル、SCANNラベルなどが代表的な例。

● □△が存在することを期待するルーチンのラベル名はEXPで始まる。それらのルーチンはR3が指しているものが□△ならばそのサイズだけR3を進め何事も無かったかのようにリターンする。□△でなかった場合はSYNTAXエラーを発生させ元の処理には戻らない。
SXP□△はR3が指す空白をスキップしてからEXP□△を行う。LXP□△は実行ポインタをR3にロードしてからSXP□△を行う。