Changes between Initial Version and Version 1 of Ex03_CA_2022


Ignore:
Timestamp:
Apr 21, 2022 12:19:48 PM (4 years ago)
Author:
nakasato
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Ex03_CA_2022

    v1 v1  
     1トップ:http://galaxy.u-aizu.ac.jp/note/wiki/CAEX2022 
     2 
     3= 今回の課題: サブルーチンを使ったプログラム =  
     4以下の2つのプログラムの説明とソースコード、実行結果をまとめてレポートを提出すること。 
     5 
     6課題3では、 課題1の命令表に掲載されている 命令に加え、サブルーチンを実装するために、jal (jump and link)命令と jr (jump register) 命令を使用してください。 
     7 
     8= 課題3−1:行列積 = 
     9以下のC言語で書かれた行列乗算のプログラムを参考にして、行列積C = A x Bを計算するプログラムを作ってください。 
     10 
     11 1. 課題2で作成した乗算のプログラムを以下のようにサブルーチン化し、メインプログラムから呼び出して使うこと。 
     12 1. サブルーチンのラベルは「MUL」にする。 
     13 1. 引数は$a0と$a1を介して引き渡す。 
     14 1. このサブルーチンでは結果は$v0に保持する。 
     15 1. メインプログラムでは、計算結果$v0を使って行列積を計算する。 
     16 
     17== 行列A == 
     18{{{ 
     190  1  0  0 
     202  0  0  0  
     210  0  0  3 
     220  0  4  0 
     23}}} 
     24 
     25== 行列B == 
     26{{{ 
     271  2  3  4 
     285  6  7  8  
     299 10 11 12 
     3013 14 15 16 
     31}}} 
     32 
     33== 初期化部分 == 
     34{{{ 
     35        .data  
     36A:      .word 0  
     37        .word 1  
     38        .word 0  
     39        .word 0  
     40    ... 配列Aの要素を書く ....  
     41 
     42B:      .word 1  
     43        .word 2  
     44        .word 3  
     45        .word 4  
     46    ... 配列Bの要素を書く ....  
     47 
     48C:      .space 64 ## 結果行列の保存用 
     49 
     50       ... 必要な変数の領域を追加する .... 
     51        .text  
     52main:  
     53exit:   j exit 
     54}}} 
     55 
     56== C言語バージョン == 
     57{{{ 
     58 
     59#include <stdio.h> 
     60main() 
     61{ 
     62  static int mat1[4][4] = { 
     63    { 1, 0, 0, 0 }, 
     64    { 0, 1, 0, 0 }, 
     65    { 0, 0, 1, 0 }, 
     66    { 0, 0, 0, 1 }, 
     67  }; 
     68  static int mat2[4][4] = { 
     69    {  1,  2,  3,  4 }, 
     70    {  5,  6,  7,  8 }, 
     71    {  9, 10, 11, 12 }, 
     72    { 13, 14, 15, 16 }, 
     73  }; 
     74  static int result[4][4]; 
     75 
     76  int  i, j, k; 
     77  int  s; 
     78  int  m1, m2; 
     79 
     80  /* 行列の乗算 */ 
     81  for( i = 0; i < 4; i++ ) { 
     82    for( j = 0; j < 4; j++ ) { 
     83      s = 0; 
     84      for( k = 0; k < 4; k++ ) { 
     85        mask = 1; 
     86        m1 = mat1[i][k];  /* 被乗数 */ 
     87        m2 = mat2[k][j];  /* 乗数 */ 
     88        s += m1 * m2 
     89      } 
     90      result[i][j] = s; 
     91    } 
     92  } 
     93 
     94  /* 結果の表示 */ 
     95  for( i = 0; i < 4; i++ ) { 
     96    for( j = 0; j < 4; j++ ) { 
     97      printf("%3d", result[i][j]);  
     98    } 
     99    printf("\n"); 
     100  } 
     101} 
     102}}} 
     103 
     104= 課題3−2:再帰的手続き = 
     105教科書第5版上巻p.99にある階乗を計算する再帰的手続きをもとに、スタックレジスタ($sp)の使いかたを理解します。 
     106メインプログラムは、ラベルmainからはじまり、$a0にNをセットして手続きfactを呼び出します。 
     107Nは要素数を指定し、結果はFNに格納します。 
     108 
     109この手続きは自分自身を呼び出すので、$a0と$raレジスタをスタックに保持する必要があります。 
     110 
     111{{{ 
     112        .data  
     113N:      .word 5  
     114FN:     .word 0  
     115 
     116.text  
     117main:   lw $a0, N         # $a0(= N) = 10  
     118        jal fact          # $v0 = fact($a0)  
     119        sw $v0 FN         # FN = $v0  
     120        exit: j exit  
     121 
     122fact:   addi $sp, $sp, -8  
     123        sw $ra, 4($sp)  
     124        sw $a0, 0($sp)  
     125 
     126        slti $t0, $a0,1   # $t1 = ($a0 < 1) 1:0  
     127        beq $t0, $0, L1   # if $t1 = 0 then L1  
     128 
     129        addi $v0,$0,1     # $v0 = 1  
     130        addi $sp,$sp,8    # $sp = $sp + 8  
     131        jr $ra            # return FN = 1  
     132 
     133L1:     addi $a0,$a0,-1  
     134        jal fact          # fact($a0 - 1)  
     135        lw $a0, 0($sp)  
     136        lw $ra, 4($sp)  
     137        addi $sp,$sp,8  
     138        mul $v0,$a0,$v0  
     139        jr $ra 
     140}}} 
     141 
     142 
     143このプログラムをシミュレータで実行し、サブルーチン"fact"の動作を確認した上で、 
     144課題3-1で作成した積を計算するサブルーチンを、スタックを使って引数をやり取りするように変更したうえで、 
     145このプログラムの"mul"命令の呼び出し部分を置き換えて、全体を完成させてください。 
     146 
     147N = 5、8の時に、正しく階乗が計算できていることの動作を確認しなさい。 
     148特に、スタックポインタ($sp)について理解すること。 
     149 
     150= Ex03のレポート = 
     151課題3-1, 3-2についてついて、プログラムの説明を書き、ソースファイルを添付してレポートを提出してください。 
     152プログラムの細かな説明は、ソースファイルにコメントの形で埋め込んでも構いません。 
     153xspimに表示される実行後のメモリの値をウィンドウ画像ダンプ等で取得し、乗算結果の部分を丸で囲むなどして強調した上でレポートに含めてください。