Changes between Version 10 and Version 11 of Ex01 MIPSアセンブリの基礎2015


Ignore:
Timestamp:
Apr 12, 2015 11:52:28 AM (11 years ago)
Author:
nakasato
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Ex01 MIPSアセンブリの基礎2015

    v10 v11  
    235235exit:   j exit 
    236236}}}  
     237 
     238上の2番目のアセンブラソースファイルをエディタにカット&ペーストして、SPIM上で動作を確認してみてください。 
     239レジスタをインクリメントしながらメモリにアクセスする方法を理解してください。  
     240 
     241= 条件分岐 = 
     242本演習で利用可能な命令の中で、条件分岐に利用できるのはbranch on equal命令だけです。 
     243例えば、C言語での以下の条件分岐は 
     244{{{ 
     245if( i == j) goto label 
     246: 
     247label: 
     248}}} 
     249以下のbeq命令と同等です。 
     250{{{ 
     251beq $i,$j,label 
     252}} 
     253 
     254== 大小比較 == 
     255大小比較をするには、set on less than命令、あるいはset less than imm命令と、beq命令を組み合わせて実現します。 
     256=== C言語 === 
     257{{{ 
     258if(a > b) {サブプログラム1}else {サブプログラム2} 
     259}}} 
     260 
     261=== MIPSアセンブリ === 
     262{{{ 
     263lw $8, a // $8 = a 
     264lw $9, b // $9 = b 
     265slt $8,$9,$8 // $8 = if ($9<$8) $8=1;else $8=0 
     266beq $8,$0,label1 // if $8=0 then goto label1 
     267{サブプログラム1に対応するアセンブラプログラム} 
     268goto label2 
     269label1: 
     270{サブプログラム2に対応するアセンブラプログラム} 
     271label2: 
     272}}} 
     273 
     274「 <=」による条件分岐をどのように実現するか、また、「if (条件1 || 条件2)」や「if (条件1 && 条件2)」をどのように実現するかは各自検討してください。 
     275 
     276== while文 == 
     277=== C言語 === 
     278{{{ 
     279while(条件){ サブプログラム} 
     280}}} 
     281 
     282=== MIPSアセンブリ === 
     283{{{ 
     284label1: 
     285$a ← if (条件) 1 else 0 
     286beq $a,$0,label2 
     287(サブプログラムに対応するアセンブラプログラム) 
     288goto label1 
     289}}} 
     290なお、条件が等式の場合は$aを用いず、直接beq命令で等式判定をします。 
     291 
     292== for文 == 
     293{{{ 
     294for( i = init_value; i < terminate_value ;更新式){サブプログラム} 
     295}}} 
     296のようなfor文は、while文を使って 
     297{{{ 
     298i = init_value; 
     299while(i < terminate_value){ 
     300サブプログラム; 
     301更新式} 
     302}}} 
     303と置き換えることができるので、while文のアセンブリプログラムを応用することで変換可能です。 
     304このとき、iの値をレジスタに保持しておくと、iへのswやlw命令を省略でき、 
     305高速化が行えますが、繰り返しの中で自由に使えるレジスタが減ってしまいます。 
     306多重ループの場合は、内部の繰り返しに優先してfor文の制御変数(今の場合i)をレジスタに割り付けるといいでしょう。 
     307この場合繰り返しの最後に、レジスタの値をメモリに書き戻さないと、正しい最適化とはなりません. 
     308 
     309= 例題3 アセンブラでのループ S=Σi=1..ni = 
     310この例題では、1からnまでを単純に加算するプログラムを扱います。 
     311== C言語 == 
     312{{{ 
     313main()  
     314{  
     315  int i = 0;  
     316  int n = 15;  
     317  int s = 0; 
     318  while( i != n ) {  
     319     i++;  
     320     s += i;  
     321  }  
     322} 
     323}}} 
     324総和演算のような処理は処理はwhile文を用いることによって記述できます。 
     325 
     326=== MIPSアセンブリ === 
     327アセンブラでは、分岐命令と比較命令を用いてループを実現します。メモリの初期状態を以下のように仮定しましょう。  
     328  
     329|| アドレス || データ || 
     330|| n || 15 || 
     331|| s ||         結果の格納 || 
     332 
     333このコードをアセンブラに変換します。 
     334ループ変数 i を$8、n の値が入っているレジスタを$9とすると、ループの部分は次のように書けます。  
     335 {{{ 
     336         or  $8, $0, $0           # i = 0  
     337loop: beq  $8, $9, loopend  # i == n なら loopend へ飛ぶ  
     338         addi $8, $8, 1             # i++  
     339   
     340        ・・・・ループの中身・・・・・  
     341   
     342         j loop  
     343loopend: 
     344}}} 
     345 
     346例題のソースファイル全体は次のようになります。  
     347{{{  
     348         .data  
     349n:       .word 15  
     350s:       .word 0 
     351         .text  
     352main:    or   $8, $0, $0       # i = 0  
     353         lw   $9, n            # nの値をロード  
     354         or   $10, $0, $0      # s = 0 
     355 
     356loop:    beq  $8, $9, loopend  # i == n なら loopend へ  
     357         addi $8, $8, 1        # i++  
     358         add  $10, $10, $8     # s += i  
     359         j    loop 
     360 
     361loopend: sw   $10, s           # sの値をストア 
     362 
     363exit:    j    exit 
     364}}} 
     365 
     366= 課題2 配列の総和計算 = 
     367メモリ上に並んだN要素からなる配列の総和を求めるプログラムを作成し、SPIMシミュレータで動作確認を行ってください。 
     368プログラムの先頭部分(配列データ)には下のコードを使用してください。  
     369 {{{ 
     370        .data  
     371N:     .word 10    # The length of Array  
     372A:     .word 8     # A[0] = 8  
     373        .word 4     # A[1] = 4  
     374        .word 7  
     375        .word 12  
     376        .word 13  
     377        .word 19  
     378        .word 23  
     379        .word 43  
     380        .word 56    # A[8] = 56  
     381        .word 32    # A[9] = 32  
     382S:      .word 0 
     383        .text  
     384main:  
     385}}} 
     386 
     387= 課題3 配列のコピー = 
     388メモリ上に並んだN要素からなる配列Aの内容を別の配列Bにコピーするプログラムを作成し、シミュレータで動作確認を行ってください。 
     389プログラムの先頭部分には、下のコードを使用して下さい。  
     390{{{  
     391       .data  
     392N:    .word 10    # The length of Array  
     393A:    .word 8      # A[0] = 8  
     394        .word 4     # A[1] = 4  
     395        .word 7  
     396        .word 12  
     397        .word 13  
     398        .word 19  
     399        .word 23  
     400        .word 43  
     401        .word 56    # A[8] = 56  
     402        .word 32    # A[9] = 32  
     403B:      .space 40   # 配列B の格納先 大きさは40バイト 
     404        .text  
     405main:  
     406}}} 
     407 
     408 
     409 
     410 
     411