2022-12-20 22:17 — asano
カテゴリー:
前回枠組みができたので実際に変更していきます。
直接アドレスやJR
, CALR
などの相対アドレスはアセンブラが良きに計らってくれるので書き直す必要はありません。
問題はレジスタ間接(インデックスなども含む)です。これは単純に書き換えられない上に、アドレスレジスタが隣り合う2つのレジスタをペアにする関係でレジスタの割り当てを大きく変更する必要がありました。幸いレジスタ数に余裕があったためレジスタ番号の書き換え程度で済んでいますが、不足する場合はメモリに退避するなど変更規模が大きくなってしまいます。
今回は大きく3つのパターンで対応しました。
単純に32ビットレジスタへ置き換え
レジスタ間接のまま32ビット化するのが一番手っ取り早いのですが、レジスタをペアで使用するので多用するとレジスタが足りなくなる恐れがあります。
これはどこを指すかわからない場合に使用しました。具体的にはSTROUT
ルーチンへの引数と各コマンドでの対象メモリへのアクセスです。
前者についてはモニタ内の固定文字列の出力にしか使用していないので後述のインデックスでも可能なのですが、文字列出力はモニタ外からも使用できるようにしておいた方が便利だろうということでレジスタ間接を使用しています。
後者はもちろんユーザがどこにアクセスしようとするかはわからないので必然的にレジスタ間接になります。
ポインタから配列へ
これまで入力バッファのアドレスをR1
に入れて@R1
でアクセスしていたのを、先頭からのオフセットに変更しINBUF(R1)
でアクセスするようにします。
*p++
からINBUF[i++]
に置き換えるようなものです。
アクセスする命令に32ビットの先頭アドレスが付くのでコードが長くなってしまうのですが...
アクセスするのはGETLIN
, RDHEX
, SKIPSP
など限られたルーチンがほとんどなのでそれほどの悪影響はありません。一方、これらのルーチンを汎用に使うことはできなくなってしまいました。
D(ump)コマンドのアスキー表示用バッファも同様です。
レジスタ関係テーブルのリンク
主にレジスタ関係の処理でテーブルを多用しています。これらのテーブルはポインタでリンクしているので、ポインタを32ビットにするとテーブルサイズが変わってしまいます。また数も多いのでテーブルサイズがかなり大きくなってしまいます。
そこで...
これもインデックスアドレッシングに書き換えました。ただ原点をどこにするか、少し悩んだ挙句セグメントの先頭にしました。こうするとオフセットの算出が楽になります。
元々1(R4)
のようにインデックスを使っていたところは原点+1のようにします。定数同士なのでアセンブル時に解決されます。
コードとしては簡単なのですが、セグメントモードと非セグメントモードでソースを共有するのがちょっと面倒でした。
CSEG0 = (CODE_B & 0FFFF0000H)
といった変な式があるのはそのためです。
前回示したAR1
のようなレジスタの置き換えも含め、セグメント / 非セグメントモードでソースを共通にできるメリットの半面、ソースの字面がZ8000らしくなくなってしまいます。
コメントを追加