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

課題:
機械命令を使った最大値を求めるプログラムを題材にして、 マイクロプログラム 'MICROONE' の変更によって機械命令を拡張することを考える。

このプログラムでは、 ラベル DATA から並んだ16個のデータの中から最大値を見つけ出し、 その結果をラベル RESULT の場所に格納している。 MICRO-1に追加する「最大値を求める命令」は Raで指定したレジスタにデータの先頭アドレス、NDにデータの個数を設定すると、 データを検索し、その最大値を求める。 求めた最大値を Rbで指定したレジスタに格納する。

「最大値を求める命令」を使った場合の機械語プログラムでは 元のプログラムのループ処理(最大値を求める処理部分)を 1つの機械命令(EX命令)に置き換えている。

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

'MICROONE' 中でEX命令を処理している部分を変更することで、 最大値を求める追加命令を実現し、 シミュレータ上で実行せよ。

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

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

実行ステップ数がどう変わったか? 何故そうなるのか? を必ず説明すること。
(ヒント: 専用命令を使う場合、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.   レジスタ4番(=命令レジスタND部の値が格納されている)の値をカウンタCにセット
  2.   もしカウンタCが0ならば(データが0個なので)ラベルEX3へ分岐
      同時にレジスタRAの値をレジスタ5番にセット
  3.   メモリ読み出しサイクル開始
      同時にレジスタ5番の値を+1し、カウンタCの値を1減らす
  4.   もしカウンタCが0ならば(データが0個なので)ラベルEX3へ分岐
      同時にメモリから読み出した値をレジスタRBにセット
  5. EX1:
      メモリ読み出しサイクル開始
      同時にレジスタ5番の値を+1し、カウンタCの値を1減らす
  6.   メモリから読み出した値をレジスタ4番にセット
  7.   レジスタRBの値とレジスタ4番の値を比較
  8.   比較の結果、レジスタRBの値がレジスタ4番より大きい場合ラベルEX2へ分岐
  9.   (最大値を更新するため)レジスタ4番の値をレジスタRBにセット
          ※常にレジスタRBに最大値が格納されるようにする
  10. EX2:
      もしカウンタCの値が0であれば(すべて調べ終わったので)ラベルEX3へ分岐
  11.   ラベルEX1へ分岐(ループの先頭に戻る)
  12. EX3:
      (これで命令の実行が終了なので)命令サイクルの最初に戻る
※上記とは別のやり方で求めても構わない。

ヒントにおける注意点

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