Changes between Initial Version and Version 1 of Ex03 サブルーチンの実装2017


Ignore:
Timestamp:
May 1, 2017 6:57:53 PM (9 years ago)
Author:
nakasato
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Ex03 サブルーチンの実装2017

    v1 v1  
     1トップ:http://galaxy.u-aizu.ac.jp/note/wiki/CAEX2016 
     2 
     3= swap手続き = 
     4第4版教科書上巻p.137の「2.13 Cプログラムの包括的な例題解説」にあるswap手続き(関数)を 
     5本演習で利用可能な命令で実装したプログラムを示します。 
     6教科書の該当分をよく読んで、C言語とMIPS命令との対応を理解すること。 
     7 
     8== C言語 == 
     9{{{ 
     10void swap(int v[], int k) 
     11{ 
     12  int temp; 
     13  temp = v[k]; 
     14  v[k] = v[k+1]; 
     15  v[k+1] = temp; 
     16} 
     17}}} 
     18 
     19== アセンブリプログラム == 
     20{{{ 
     21swap:    addi $t1, $a1, 0  
     22         add $t1, $t1, $t1  
     23         add $t1, $t1, $t1  
     24         add $t1, $a0, $t1  
     25         lw $t0, 0($t1)  
     26         lw $t2, 4($t1)  
     27         sw $t2, 0($t1)  
     28         sw $t0, 4($t1)  
     29         jr $ra 
     30}}} 
     31 
     32引数の受け渡しは$a0と$a1のレジスタを使います。 
     33ここでは、$a0でswapされる整列させる配列の先頭アドレスを、$a1でswapする箇所の配列の添え字(k)を受け渡します。 
     34 
     35シフト命令は利用できないので、add命令の組み合わせで「k*4」を実現しています。 
     36 
     37== 練習課題1 == 
     38以下のテンプレートと組み合わせて、swap関数の動作を確認すること。 
     39 
     40{{{ 
     41       .data  
     42k:     .word 3  
     43A:     .word 32  
     44       .word 422  
     45       .word 83  
     46       .word 2  
     47       .word 92  
     48       .word 32  
     49       .word 97  
     50       .word 22  
     51       .word 4  
     52       .word 86  
     53 
     54       .text  
     55main:  la $a0, A  
     56       lw $a1, k  
     57       jal swap  
     58exit:  j exit  
     59}}} 
     60 
     61= ソート手続き = 
     62教科書に従い、swap関数を使って単純なソートプログラムの動作を確認します。 
     63 
     64{{{ 
     65       .data  
     66N:     .word 3  
     67A:     .word 32  
     68       .word 422  
     69       .word 83  
     70       .word 2  
     71       .word 92  
     72       .word 32  
     73       .word 97  
     74       .word 22  
     75       .word 4  
     76       .word 86  
     77 
     78       .text  
     79main:  la $a0, A  
     80       lw $a1, N  
     81       jal sort  
     82exit:  j exit  
     83 
     84sort:  addi $sp, $sp, -20  
     85       sw $ra, 16($sp)  
     86       sw $s3, 12($sp)  
     87       sw $s2, 8($sp)  
     88       sw $s1, 4($sp)  
     89       sw $s0, 0($sp)  
     90 
     91       or $s2, $0, $a0     #move $s2, $a0  
     92       or $s3, $0, $a1     #move $s3, $a1  
     93 
     94       or $s0,$0,$0        # $s0(= i) = 0  
     95 
     96for1tst: slt $t0,$s0,$s3     # $t0 = (i < N) 1:0  
     97         beq $t0,$0,exit1    # if $t0 == 0 then exit1  
     98         addi $s1, $s0, -1   # j = i - 1  
     99 
     100for2tst: slti $t0, $s1, 0    # $t0 = (j < 0) 1:0  
     101         beq $t0, $0, cont   #bne $t0, $0, exit2 変更点2  
     102         j exit2  
     103 
     104cont:    or $t1, $s1, $0     # $t1 = j * 4  
     105         add $t1, $t1, $t1   #変更点3  
     106         add $t1, $t1, $t1  
     107 
     108         add $t2, $s2, $t1   # $t2 = &(A[j])  
     109         lw $t3, 0($t2)      # $t3 = A[j]  
     110         lw $t4, 4($t2)      # $t4 = A[j+1]  
     111 
     112         slt $t0, $t4, $t3   # $t0 = (A[j]< A[j+1]) 1:0  
     113         beq $t0, $0, exit2  # if $t0 == 0 then exit2  
     114         or $a0, $s2, $0     # $a0 = $s2(&A)  
     115         or $a1, $s1, $0     # $a1 = $s1(j)  
     116         jal swap  
     117 
     118         addi $s1, $s1, -1   # j = j - 1  
     119         j for2tst  
     120 
     121exit2:   addi $s0, $s0, 1    # i = i + 1  
     122         j for1tst  
     123 
     124exit1:   lw $s0, 0($sp)  
     125         lw $s1, 4($sp)  
     126         lw $s2, 8($sp)  
     127         lw $s3, 12($sp)  
     128         lw $ra, 16($sp)  
     129         addi $sp, $sp, 20  
     130         jr $ra  
     131}}} 
     132 
     133sort関数の引数の受け渡しは、$a0と$a1のレジスタを使います。 
     134ここでは、$a0に整列させる配列の先頭アドレスを$a1にNをそれぞれセットしています。 
     135 
     136教科書のプログラムとの変更点は以下のところです。 
     137 * move命令をor命令に置換 
     138 * bne命令をbeqとj命令の組み合わせに置換 
     139 * sll命令をadd命令の組み合わせに置換 
     140 
     141$spは明示的に初期化されていませんが、xspimによって自動的に設定されます。 
     142 
     143== 練習課題2 == 
     144swap関数と組み合わせて、N = 3の時に正しく動作することを確認すること。 
     145また、変数Nが10の場合に正しい結果が得られることを確認すること。 
     146 
     147= 課題6:手続きを用いた行列の積アルゴリズム =  
     148第2回演習で作成した、行列の積を求めるプログラムのうち、2つの整数の積を求める部分を手続き呼び出しに置き換えなさい。 
     149 1. 手続きのラベルは「MUL」にする。 
     150 1. 引数は$a0と$a1を介して引き渡す。 
     151 1. この手続きでは結果は$v0に保持する。 
     152 1. メインプログラムでは、計算結果$v0を使って行列積を計算する。 
     153 
     154ファイル名は「ex03_p6.s」としてください。 
     155 
     156= 再帰手続き呼び出し =  
     157第4版教科書上巻p.105にある階乗を計算する再帰的手続きをもとに、スタックレジスタ($sp)の使いかたを理解します。 
     158メインプログラムは、ラベルmainからはじまり、$a0にNをセットして手続きfactを呼び出します。 
     159Nは要素数を指定し、結果はFNに格納します。 
     160 
     161この手続きは自分自身を呼び出すので、$a0と$raレジスタをスタックに保持する必要があります。 
     162 
     163{{{ 
     164        .data  
     165N:      .word 5  
     166FN:     .word 0  
     167 
     168.text  
     169main:   lw $a0, N         # $a0(= N) = 10  
     170        jal fact          # $v0 = fact($a0)  
     171        sw $v0 FN         # FN = $v0  
     172        exit: j exit  
     173 
     174fact:   addi $sp, $sp, -8  
     175        sw $ra, 4($sp)  
     176        sw $a0, 0($sp)  
     177 
     178        slti $t0, $a0,1   # $t1 = ($a0 < 1) 1:0  
     179        beq $t0, $0, L1   # if $t1 = 0 then L1  
     180 
     181        addi $v0,$0,1     # $v0 = 1  
     182        addi $sp,$sp,8    # $sp = $sp + 8  
     183        jr $ra            # return FN = 1  
     184 
     185L1:     addi $a0,$a0,-1  
     186        jal fact          # fact($a0 - 1)  
     187        lw $a0, 0($sp)  
     188        lw $ra, 4($sp)  
     189        addi $sp,$sp,8  
     190        mul $v0,$a0,$v0  
     191        jr $ra 
     192}}} 
     193 
     194== 練習課題3 == 
     195N = 5、8の時に、正しく階乗が計算できていることの動作を確認しなさい。特に、スタックポインタ($sp)について理解すること。 
     196 
     197= 課題7:手続きを用いたプログラムの作成 =  
     198下記の機能を実現する手続きを作成し、実行を確認してください。 
     199作成するプログラムでは、main関数から、作成した関数(手続き)を呼び出し、動作を確認する部分も含めること。 
     200 
     201== 16bit整数a, b, cを引数とし d = a*b + cを計算する関数: int mac(int a, int b, int c) == 
     202以下のパターンについて動作確認をすること。 
     203{{{ 
     204(a, b, c) = (11, 21, 0) 
     205(a, b, c) = (11, 21, 6) 
     206(a, b, c) = (3333, 4444, 5555) 
     207}}} 
     208 
     209ファイル名は「ex03_p7a.s」としてください。 
     210 
     211== 16bit整数aをn bit左シフトする関数:  int left_shift(int a, int n) == 
     212動作確認は”0x1”を1, 4, 7, 15 bitシフトした結果を確認すること。シフト命令を使ってはいけない。 
     213 
     214ファイル名は「ex03_p7b.s」としてください。