= !PicoBlazeAbi =
PicoBlazeのソフトウェアを作成するために使用できる言語は、基本的にはアセンブラしかありません。
ふつう、ABIはC言語とアセンブラ言語とで、お互いに呼び出しを行うための決まりごと(CコンパイラがCソースを機械語に翻訳するときの規則)のことなので、アセンブラしかないPicoBlazeにはABIなんてものはありません。
しかし、アセンブラだけでプログラムを書くとしても、いちいち「破壊レジスタ」が何であるかを気にしながらサブルーチンを呼び出すのは面倒なので、自分で書くルーチンに関しては自分で考えた規則でレジスタを操作することにしました。(オレ策定・オレ適用のオレオレABIです)
なお、PicoBlazeにはCALL/RETURN用のスタックは存在してもデータ用のスタックが存在しないので、このABIに準拠するためには!ScratchPadをスタックとして使う[http://sourceforge.jp/projects/noodlybox/svn/view/trunk/pblaz/sw/dstack.asm?view=co&root=noodlybox データスタックを実現するライブラリ]の使用がほぼ必須となります。
= 言葉の定義 =
ローカル~
ローカルとは、呼び出し元が不特定多数でなく、ある特定のルーチンからのみ呼び出されることを示します。
ABIの適用はされませんので、効率を優先してかまいません。
ローカルラベル
特定のルーチンからのみJUMP先として指定されるラベルのことです。
ローカルルーチン
特定のルーチンからのみCALL先として指定されるラベルのことです。
グローバル~
不特定多数の呼び出し元から参照されるラベルのことです。
= レジスタの使われ方 =
s0 ~ s5 の6個 : スクラッチ
* 呼び出され側で自由に破壊できます。
* 呼び出し側から呼び出され側へ、引数を渡すために使用されます。
* 呼び出され側から呼び出し側へ、戻り値を渡すために使用されます。
s6 ~ sE の9個 : 通常
* 呼び出され側は破壊してはいけません(CALL直後の値とRET直前の値が同一であることを保証しなければなりません)。
* サブルーチンから戻ってきた後でも継続して使用したい値を格納するために、しばしば使用されます。
* 呼び出し側から呼び出され側へ、s0~s5では足りない場合に、引数を渡すために使用されます。
sF : データスタックポインタ
* スクラッチパッド内の領域をデータスタックとして活用するために使用されます。
Z,Cフラグ
* ローカルでないすべてのサブルーチンにおいて、呼び出され側は破壊してはいけません(CALL直後のフラグ状態と、RET直前のフラグ状態が同一であることを保証しなければなりません)。
* サブルーチン先頭でCALL pushEFlagを行い、かつ、RET直前にCALL popEFlagを行うことで、フラグの保持ができます。
* 例外的に、bool値を返すサブルーチンでは、呼び出し側の条件ジャンプに供するために、ZおよびCフラグを更新してリターンすることができます。
* Z,Cを保持する意義は?
* たとえば、s0の値が0か1かでLCDに表示するメッセージを変えたいとき、普通は
{{{ code asm
LOAD s6, s0
COMP s6, 0
CALL Z, PUTMSG_ZERO
COMP s6, 1
CALL Z, PUTMSG_ONE
}}}
と書きますが、呼び出し後でもZ,Cが変わらないことを期待できるなら以下のように書くことができます。
{{{ code asm
COMP s0, 1
CALL C, PUTMSG_ZERO
CALL Z, PUTMSG_ONE
}}}
= コーディングルール =
ローカルラベル
* ローカルなサブルーチンやローカルなジャンプ先には、'_'で始まる名前を付けます。
* 例
* _wait_loop
他バンクへのラベル
* 本体が別のバンクにあるサブルーチンには、'_'で終わる名前を付けます。
* 例
* init_LCD_