課題5.マイクロプログラムを変更してMICRO-1機械命令の拡張を行う

課題:
文字列をコピーするプログラムを題材にして、 マイクロプログラム 'MICROONE' の変更によって機械命令を拡張することを考える。

このプログラムは ラベル DATA から並んでいる整数データを文字列とみなし、 終端記号(0x00)が見付かるまで、ラベル RESULT以降に値をコピーする。

このプログラムにおいて、 ループ処理により文字列のコピー処理を行っている部分を機械命令化することで、 実行サイクル数が少なくすることができると考えられるので、 MICRO-1機械命令マイクロプログラム 'MICROONE' を元にして 文字列コピー命令を追加する。

追加する命令を機械語プログラムから使用する際には、EX命令を使う。 機械語プログラム中でEX命令を使う場合は、I型命令と同様の表記をする。

EX 1,(2)     ; (Ra部=2, Rb部=1, ND部=0  (※この課題ではND部を使用しない))
MICRO-1に追加する「文字列をコピーする命令」は Raで指定したレジスタにコピー元の文字列の先頭アドレス、 Rbで指定したレジスタにコピー先のアドレスを設定すると、 Raから始まる文字列を、Rbのアドレスにコピーする。

「文字列をコピーする命令」を使った場合の機械語プログラムでは 元のプログラムのループ処理(終端文字が見付かるまで文字をコピーする処理の部分)を 1つの機械命令(EX命令)に置き換えている。

このプログラムと命令追加の変更を行った 'MICROONE' を組み合わせて実行する。

'MICROONE' 中でEX命令を処理している部分を変更することで、 追加命令「文字列をコピーする命令」を実現し、 シミュレータ上で実行せよ。

検索対象データの値(ラベル DATA 以降に格納されている値)を変えて、 それぞれについて動作確認を行うこと。

また、課題4と同様に、元のプログラム strcpy と実行ステップ数を比較して、考察せよ。

実行ステップ数がどう変わったか? 何故そうなるのか? を必ず説明すること。
(ヒント: 専用命令を使う場合、1つの命令で多くの処理を担うことになるため、 命令サイクルのうちフェッチフェーズの処理回数が減ることになる)

注意1
'MICROONE'を修正するとその実行開始アドレス(デフォルトは101)も変わるため、 機械語プログラムを実行するときに指定する開始アドレスに注意する。 変更後の 'MICROONE' の実行開始アドレスを調べるためには、 'MICROONE.M' の中身を調べてラベル INIT のアドレス値を調べるとよい。
例えば、ラベル INIT のアドレス値が 10B であった場合は、 マイクロプログラムの実行開始アドレスも 10Bにすること。
※マイクロプログラム中の命令を追加あるいは削除した場合、このアドレス値も変化 するため、毎回確認すること。

注意2
マイクロプログラム 'MICROONE' の中では レジスタの6番と7番(R6, R7)はそれぞれ、 サブルーチン呼び出し時の戻り先PC値の保存の際に用いるスタックポインタ、 PUSH/POP命令でレジスタ値の保存の際に用いるスタックポインタ として使われているため、値を勝手に変更すると不具合を生じる場合がある。
またレジスタ0番から3番(R0〜R3)は機械語プログラムでも使用されるため、 これらのレジスタについても値を勝手に変更すると機械語プログラムが 正しく動作しなくなる可能性がある。

もしこれらのレジスタを使いたい場合は、 一旦レジスタの値をメモリ上に保存してから使用すること。 また、レジスタを使い終わったら、 メモリ上に保存しておいた値をレジスタにセットして元の値に戻すこと。

レジスタ4番と5番(R4, R5)については自由に使うことができる。
レジスタ4番(R4)にはフェッチフェーズにおいて 命令レジスタIRのND部の値が格納されているので、 必要に応じてこの値を使用することが出来る。

ヒント
'MICROONE' 内の(ファイルの最後の方にある)ラベル EX0 辺りから EX命令用のマイクロ命令を記述すればよい。
処理の内容としては以下のようなことを記述すればよいと考えられる。
※番号のついた各項目がそれぞれ一つのマイクロ命令に対応していると 考えてよい。

  1. EX0:
      RAをレジスタ5番にコピーする
  2.   メモリ読み出しサイクル開始
      同時にレジスタ5番の値を+1した値を RAに格納する (これによりレジスタ5番の値がLBUSにセットされることに注意)
  3.   メモリからの読み出しデータをレジスタ5番(R5)にセット
  4.   メモリ書き込みサイクル開始
      RBの値を1だけ増す (これによりRBで指定された番号のレジスタの値がLBUSにセットされることに注意)
  5.   レジスタ5番の値でフラグを更新する(SET BYを使う)
  6.   ゼロでない場合ラベルEX0へ分岐
  7.   (これで命令の実行が終了)命令サイクルの最初に戻る
※上記とは別のやり方で求めても構わない。

ヒントにおける注意点

文責:大津 (協力:横田)