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


Ignore:
Timestamp:
Apr 14, 2015 9:44:35 AM (11 years ago)
Author:
nakasato
Comment:

--

Legend:

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

    v26 v27  
    5656 
    5757= 例題1:変数の代入 =  
    58 変数A, B, Cがある時に「C = A + B」を実現するプログラムを考える 
    59  
    60 変数A,B, Cは、メモリ上に以下のように配置されているとします。 
    61 それぞれは32ビットワードの変数であり、変数につき4バイトのアドレス空間を占めます。  
     58変数A, B, Cがある時に「C = A + B」を実現するプログラムについて検討します 
     59 
     60変数A, B, Cは、メモリ上に以下のように配置されているとします。 
     61それぞれは32ビットワードの変数であり、1変数につき4バイトのアドレス空間を占めます。  
    6262  
    6363|| 変数 || アドレス(16進数) ||  初期値(10進数) || 結果(10進数) || 
     
    6565||     B|| 0x4|| 75|| 75|| 
    6666||     C|| 0x8||  0|| 94|| 
    67 / 
    68 MIPSプロセッサでの演算はレジスタ間でのみ行うことができます。 
     67 
     68MIPSプロセッサでの演算はレジスタ間でのみ行うことができます。 
    6969したがって、メモリの中のデータを演算するためには一度レジスタの中にデータをロードし、 
    7070演算を行った後に演算結果をメモリにストアしなければなりません。 
     
    8686このプログラムを「sum1.s」としてファイルに保存し、xspimでシミュレーションを行ってください。 
    8787 
    88 アセンブリプログラムで、「.data」から始まる部分をデータセグメントと呼びます。 
     88アセンブリプログラムで「.data」から始まる部分を、データセグメントと呼びます。 
    8989各行は「32ビット数値で内容は「19」の変数を定義しそのアドレスを「A」で参照できるようにする」という意味です。 
    9090 
     
    9292各命令の概要を以下のテーブルで説明します。 
    9393 
    94 まず、このプログラムでは、レジスタ$8, $9, $10を利用していて、各行が実行される毎にその内容は変化する場合があります。 
     94このプログラムでは、レジスタ$8, $9, $10を利用しています。 
     95各行が実行される毎にその内容は変化する場合があります。 
    9596 
    9697|| 命令         || 動作 || $8の内容 || $9の内容 || $10の内容 || 
    97 || lw  $8, A  ||アドレスAのデータをレジスタ$8にロード|| 19 || 不定 || 不定 || 
    98 || lw  $9, B  ||アドレスBのデータをレジスタ$9にロード|| 19 || 75 || 不定 || 
    99 || add  $10, $8, $9  ||レジスタ$8と$9を加算して、結果を$10に格納|| 19 || 75 || 94 || 
    100 ||sw   $10, C  ||レジスタ$10の内容をアドレスCにストア|| 19 || 75 || 94 || 
    101 ||j  exit  ||ラベルexitにジャンプ || 19 || 75 || 94 || 
     98||lw  $8, A     ||アドレスAのデータをレジスタ$8にロード|| 19 || 不定 || 不定 || 
     99||lw  $9, B     ||アドレスBのデータをレジスタ$9にロード|| 19 || 75 || 不定 || 
     100||add  $10, $8, $9  ||レジスタ$8と$9を加算して、結果を$10に格納|| 19 || 75 || 94 || 
     101||sw   $10, C   ||レジスタ$10の内容をアドレスCにストア|| 19 || 75 || 94 || 
     102||j  exit       ||ラベルexitにジャンプ || 19 || 75 || 94 || 
    102103  
    103104補足:「lw $8, A」 は 「lw $8, A($0)」 の省略形であり、レジスタ$8には「A + $0」の値がロードされます。 
    104105 
    105 xpsimを実行すると以下のような画面となります。 
     106xspimを立ち上げると、以下のような画面となります。 
    106107 
    107108[[Image(http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex01%E3%80%80MIPS%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%AA%E3%81%AE%E5%9F%BA%E7%A4%8E2015/xpsim.png)]] 
    108109 
    109  
    110110画面の上段には各レジスタの内容が示されています。 
    111111 
    112 中段には各ボタンがあり、ソースファイルの読み込みには "load" ボタン、プログラムの実行には "step" ボタンをクリックします。 
    113  
    114 下段にはテキストセグメント(Text Segments)と、データセグメント(Data Segments)が示され、一番下の部分には実行時のメッセージが表示されます。 
     112中段には各ボタンがあり、ソースファイルの読み込みにはloadボタン、プログラムの実行にはstepボタンをクリックします。 
     113 
     114下段にはテキストセグメント(Text Segments)と、データセグメント(Data Segments)が示され、 
     115一番下の部分には実行時のメッセージが表示されます。 
    115116 
    116117プログラムの実行には二つの方法があり、stepボタンによる実行では、テキストセグメントの命令が一命令ずつ実行されます。 
    117 一方"run"ボタンを使うと、プログラムを一気に実行できます。 
    118  
    119 このプログラムをstep実行し、一命令ずつレジスタやデータセグメントの値が変化するのを確かめること。 
     118一方runボタンを使うと、プログラムを一度に実行できます。 
     119 
     120「sum1.s」をstep実行し、一命令ずつレジスタやデータセグメントの値が変化するのを確かめること。 
    120121 
    121122= 複雑な式の評価 = 
     
    142143 
    143144= 課題1 = 
    144 3つの変数と定数を含んだ式「S = (A + B - C) | 3」の計算を行うプログラムを作成し、SPIM上でシミュレーションを行ってください。 
     1453つの変数と定数を含んだ式「S = (A + B - C) | 3」の計算を行うプログラムを作成し、xspimでシミュレーションを行ってください。 
    145146"|" はビットごとの論理和演算です。 
    146147 
     
    156157この例題ではメモリを間接的に参照するためにレジスタ相対アドレスを用いる方法を示します。 
    157158以下のような配列変数の和を計算することを考えます。 
     159 
    158160{{{ 
    159161S=A[0]+A[1]+A[2]+A[3] 
     
    202204 
    203205また、上のプログラムは下のように書き直すこともできます。 
    204 この形は各データに対する処理が全く同じ命令列になるため、 
    205 後で述べるループを用いて和を求める場合に適しています。  
     206この形は各データに対する処理が全く同じ命令列になるため、後で述べるループを用いて和を求める場合に適しています。  
    206207 
    207208{{{ 
     
    213214S:      .word 0 
    214215        .text  
    215 main:   or   $8, $0, $0   # 和を 0 に初期化  
    216         la   $9, A        # Aのアドレスを $9 に入れる。実際は ori 命令に置き換わる。 
     216main:   or   $8, $0, $0  
     217        la   $9, A      
    217218 
    218219        lw   $10, 0($9)  
     
    235236}}}  
    236237 
    237 上の2番目のアセンブリプログラムをエディタにコピー&ペーストして、SPIM上で動作を確認してください。 
     238上の2番目のプログラムをエディタにコピー&ペーストして、xspimで動作を確認してください。 
    238239レジスタをインクリメントしながらメモリにアクセスする方法を理解してください。  
    239240 
     
    243244 
    244245{{{ 
    245 if( i == j) goto label 
    246 : 
     246if(i == j) goto label 
     247 
     248... 
     249 
    247250label: 
    248251}}} 
     
    256259== 大小比較 == 
    257260大小比較をするには、set on less than命令、あるいはset less than imm命令と、beq命令を組み合わせて実現します。 
     261 
    258262=== C言語 === 
    259263{{{ 
    260 if(a > b) {サブプログラム1}else {サブプログラム2} 
     264if(a > b) {サブプログラム1}else {サブプログラム2} 
    261265}}} 
    262266 
     
    267271slt $8,$9,$8 
    268272beq $8,$0,label1 
    269 {サブプログラム1に対応するアセンブラプログラム} 
     273 
     274サブプログラム1に対応するアセンブラプログラム 
     275 
    270276goto label2 
    271277label1: 
    272 {サブプログラム2に対応するアセンブラプログラム} 
     278 
     279サブプログラム2に対応するアセンブラプログラム 
     280 
    273281label2: 
    274282}}} 
    275283 
    276 「 <=」による条件分岐をどのように実現するか、また、「if (条件1 || 条件2)」や「if (条件1&& 条件2)」をどのように実現するかは各自検討してください。 
     284「<=」による条件分岐をどのように実現するか、また、 
     285「if (条件1 || 条件2)」や「if (条件1 && 条件2)」をどのように実現するかは各自検討してください。 
    277286 
    278287== while文 == 
    279288=== C言語 === 
    280289{{{ 
    281 while(条件){ サブプログラム} 
     290while(条件){ サブプログラム } 
    282291}}} 
    283292 
     
    287296$a ← if (条件) 1 else 0 
    288297beq $a,$0,label2 
    289 (サブプログラムに対応するアセンブラプログラム) 
     298 
     299サブプログラムに対応するアセンブラプログラム 
     300 
    290301goto label1 
    291302}}} 
     
    307318 
    308319と置き換えることができるので、while文のアセンブリプログラムを応用することで変換可能です。 
     320 
    309321このとき、iの値をレジスタに保持しておくと、iへのswやlw命令を省略でき、 
    310322高速化が行えますが、繰り返しの中で自由に使えるレジスタが減ってしまいます。 
     
    314326= 例題3 ループによる演算 = 
    315327この例題では、1からnまでを単純に加算するプログラムを扱います。 
     328 
    316329== C言語 == 
    317330{{{ 
     
    342355ループ変数 i を$8、n の値が入っているレジスタを$9とすると、ループの部分は次のように書けます。  
    343356{{{ 
    344          or  $8, $0, $0           # i = 0  
    345 loop: beq  $8, $9, loopend  # i == n なら loopend へ飛ぶ  
    346          addi $8, $8, 1             # i++  
     357      or  $8, $0, $0           # i = 0  
     358loop: beq  $8, $9, loopend      # i == n なら loopend へ飛ぶ  
     359      addi $8, $8, 1            # i++  
    347360   
    348361        ・・・・ループの中身・・・・・  
    349362   
    350          j loop  
     363      j loop  
    351364loopend: 
    352365}}} 
     
    376389プログラムの先頭部分(配列データ)には下のコードを使用してください。  
    377390 {{{ 
    378         .data  
     391       .data  
    379392N:     .word 10    # The length of Array  
    380393A:     .word 8     # A[0] = 8  
    381         .word 4     # A[1] = 4  
    382         .word 7  
    383         .word 12  
    384         .word 13  
    385         .word 19  
    386         .word 23  
    387         .word 43  
    388         .word 56    # A[8] = 56  
    389         .word 32    # A[9] = 32  
    390 S:      .word 0 
    391         .text  
     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  
     403S:     .word 0 
     404       .text  
    392405main:  
    393406}}} 
     
    397410プログラムの先頭部分には、下のコードを使用して下さい。  
    398411{{{  
    399        .data  
     412      .data  
    400413N:    .word 10    # The length of Array  
    401 A:    .word 8      # A[0] = 8  
    402         .word 4     # A[1] = 4  
    403         .word 7  
    404         .word 12  
    405         .word 13  
    406         .word 19  
    407         .word 23  
    408         .word 43  
    409         .word 56    # A[8] = 56  
    410         .word 32    # A[9] = 32  
    411 B:      .space 40   # 配列B の格納先 大きさは40バイト 
    412         .text  
     414A:    .word 8     # A[0] = 8  
     415      .word 4     # A[1] = 4  
     416      .word 7  
     417      .word 12  
     418      .word 13  
     419      .word 19  
     420      .word 23  
     421      .word 43  
     422      .word 56    # A[8] = 56  
     423      .word 32    # A[9] = 32  
     424B:    .space 40   # 配列B の格納先 大きさは40バイト 
     425      .text  
    413426main:  
    414427}}}