演習第3回:アセンブラプログラミング(1)サブルーチン(説明資料)
概要
MIPSのシミュレータspim上で実行可能なアセンブリ言語のコードを用いてプログラムを作成する。
実用的な処理を行うためのプログラムでは、ひとまとまりの処理を独立なものとして定義し、それを再利用するサブルーチンを用いる。
アセンブリ言語においては、レジスタの種類と数およびその使用目的に厳格な決まりがあるため,特にサブルーチンの使用に当たっては注意が必要である.サブルーチンにデータを渡すためにはレジスタ$a0~$a3を用いる。レジスタ$v0と$v1はサブルーチンの戻り値を格納することになっているし、$v0はシステムコール番号を設定するためにも使う。
作業用レジスタは$s0~$s7および$t0~$t9の2種類があるがサブルーチンの使用に当たっては区別して使わなければならない。$s0~$s7はサブルーチンを呼んでも呼び出し側では書き換えられない決まりになっているので、サブルーチン内で書き換える必要がある場合には、サブルーチン内で退避と復元が必要である。それに対し、$t0~$t9はサブルーチン内で書き換えても良いことになっているため、必要な場合はサブルーチンを呼び出す側で退避および復元が必要となる。
サブルーチンの使用に当たって必須であるレジスタの退避の方法としてスタック(stack)を用いる。
サブルーチンでデータを渡すレジスタは$a0~$a3の4つと決まっている。データの個数が4を超える場合はどうしたらよいのか?サブルーチンの処理結果のデータを呼び側に渡すためのレジスタは$v0と$v1の2つであるが、3つ以上のデータを返す場合はどうしたらよいか?メモリに必要な分のデータ領域を確保し,その領域のアドレスをメインルーチンとサブルーチンの間で受け渡しすれば,この問題は解決する。スタックを使うこともこの問題を解決するための必須テクニックです。
レポートの提出期限:2024年7月4日(木)23:59:59
課題1(メモリアクセス・大域配列)必須課題
キーボードから読み込んだ複数の整数値をメモリー上に一時保存し、読み込みが完了してから総和の計算を行ないたい。これを実現するための以下の2つのサブルーチンを作成せよ。実行して正しく機能することを示すこと.
その1:サブルーチンsum
【機能】引数$a0で指定されたアドレスから始まるメモリーに、引数$a1で指定された個数の32ビット整数値が格納されているとし、これらの総和を求めて、その値を$v0で返す。データ数を示す$a1は1以上の整数と仮定してよい。
sumへ渡す2つの引数は、C言語で言うと配列の先頭のポインタと配列の要素数に当たる。総和を求める対象は配列の要素に当たり、$a0 で渡されたアドレスを1ワードずつ (4バイトずつ) 増加させることで、その要素に順にアクセスすることが可能になる。C言語における、ポインタ変数 p を増加させながら値を参照する*p++ の振舞いと同等である。
sumの機能を確かめるために、下記のテスト用メインルーチンを使用しても良い。ただし、sumはこのテスト用メインルーチンに特化した実装を行なってはならない。あくまでも、上記【機能】を満たす汎用のサブルーチンである。
sumの機能を確かめるプログラムは testsum.s とする.
その2:サブルーチンread
【機能】引数$a0で指定されたアドレスから始まるメモリ領域に対し、引数$a1で指定された個数の32ビット整数をキーボードから読み込み順次格納する。C言語で言う配列に整数値を順次読み込む機能と考えてよい。データ数を示す$a1は1以上の整数と仮定してよい。
サブルーチンreadでは整数値の読み込みのためにシステムコールが必要になる。また引数として受け取った$a0、$a1もシステムコールで値が変更される可能性があるため、そのまま継続して利用するのは不適切である。
readとsum を組み合わせたの時の動作を確かめるために、下記のメインルーチンを使用してもよい。ただし、readとsumはこのテスト用メインルーチンに特化した実装を行なってはならない。あくまでも、上記【機能】を満たす汎用のサブルーチンである。
readとsumの機能を確かめる以下のプログラムは testreadsum.s とする.
課題2(サブルーチンの入れ子)「パスカルの三角形」必須課題
階乗と組み合わせの数を計算するサブルーチンfactとcombi を作成し、これを用いてn個からr個を取り出す時の組合せnCrを計算できるようにする. これを利用してパスカルの三角形を計算するプログラム pascalTri.s を作成せよ。メインルーチンの処理は以下のようなものとする。
- パスカルの三角形の高さmをキーボードから読み込む.
- mの値が0以下の場合は何も出力しない.
- mの値が1以上の場合はパスカルの三角形を計算して表示する(表示例は以下参照).
- 三角形の各段、各列に対応するnCrをサブルーチンcombiを呼び出して計算
- m≦13に対応すればよい.
※ 本課題における制約条件:
汎用的なプログラム作成の演習とするため、
main, fact, combiの各ルーチン内で使用する作業用レジスタは
それぞれ$s0〜$s7を番号の若い方から順に使用すること。
もちろん各ルーチンの実行前後でレジスタの値が変わらないよう一時待避が必要である 。
サブルーチンfact
【機能】引数$a0で指定された非負整数の階乗を求め、その値を$v0で返す。再帰計算ではなく,繰り返し計算を用いること。
サブルーチンcombi
【機能】引数$a0を n、引数$a1をrとした時の組合せの数nCrを上記のサブルーチンfactを用いて求め、その値を$v0で返す。なお、n個からr個を取り出す時の組合せの数nCrは、factによる階乗の計算を使い以下のように求めること。

補足:整数除算はdiv $rs, $rtで計算できる。結果は商がLoレジスタ、余りがHiレジスタに入る。
課題3自由課題
課題2では作業用レジスタの使用に制約を課した。この制約を外すことによりレジスタの退避・復元の手間を最少化したプログラムを作れ.
プログラムのファイル名は課題2のファイル名に適当な文字列を追加したもの(例えば pascalTri_opt.s )とすること.
これを完成して提出した場合はレポート内容点に加点する.