1

以下のコードのいくつかのMIPS命令について質問があります
。1。addi算術命令ですが、その目的は何ですか。
2.なぜとのnop後に単一がありますが、後に複数のがありますか? ありがとう !jbeqnopaddi

if(a==b)  x=3; /* simple C code */
else      x=4;
y=5;  

       lw   $1,a       # possible unoptimized assembly language
       lw   $2,b       # no ($0) shown on memory access
       nop             # wait for b to get into register 2
       nop             # wait for b to get into register 2
       beq  $1,$2,lab1
       nop             # branch slot, always executed *********
       addi $1,4       # else part
       nop             # wait for 4 to get into register 1
       nop             # wait for 4 to get into register 1
       sw   $1,x       # x=4;
       j    lab2
       nop             # branch slot, always executed *********    
lab1:  addi $1,3       # true part  
       nop             # wait for 3 to get into register 1
       nop             # wait for 3 to get into register 1
       sw   $1,x       # x=3;  
lab2:  addi $1,5       # after if-else, always execute
       nop             # wait for 5 to get into register 1
       nop             # wait for 5 to get into register 1
       sw   $1,y       # y=5;
4

3 に答える 3

3

addiは「即時追加」であり、レジスタの内容に即時値(定数、整数)を追加します。他の加算バリアントは、レジスタを使用したレジスタ加算です。

addiの後のnopsと説明は、mipsの観点からはまったく意味がありません。Mipsは教育目的でよく使用され、使用中または教えられている特定の実装では、addi命令がデコードして実行し、結果をレジスタファイルに格納してから、そのレジスタを別の命令への入力として使用できるようになるまでに時間がかかる場合があります。通常、mipsコア(またはそのことについては最新のパイプラインプロセッサ)は、次の命令をブロックするか、他のソリューションを使用して、次の命令への入力である1つの命令の結果をショートカットします。

コメントがレジスタに格納される結果を示しているように、これらのnopが時間を遅らせるために使用されるのはaddiだけでなくlwでもあります。

少なくとも基本的な手順、フェッチ、デコード、実行、結果の保存について考えてください。このコードは、実際のmipsが完了する必要がない場合でも、これらのステップの少なくとも一部が完了するのに時間をかけているようです。

分岐の後に遅延スロットを設けることは非常に簡単なことです(他の人がそうすることを確認してくださいが、それは一般的よりもまれです)。それを行う簡単な方法は、すべてのブランチの後にnopを置くか、ジャンプしてサイクルを無駄にすることです。最終的には、ブランチの前に指示の1つを取り、それを後に置くことができる場合を学習します。それ以外の場合は、nopを使用します。

一般的に、コードは正常に見えます。コードがCコードを表すようにaddi命令が機能するためには、addiは実際には常にゼロであるレジスタ0を使用する必要があります。Addiはレジスタを取得し、すぐにそれらを加算して結果を別のレジスタに入れます。addiには2つのレジスタがあり、定数は1つです...あなたが持っているコードは1つのレジスタしか示していません。あなたがそれをこのように考えるならば、そのコードでのaddiのすべての使用のために:

addi $1,4 
changes to 
addi $1,$0,4
register $0 is always zero so this instruction really means
$1 = 0 + 4 = 4
$1 = 4

私は、正式な観点とマシンコードの観点からmips命令を知っています。おそらく、addi $ 1,4は、より正式なaddi $ 1、$0,4を表すショートカットです。コードをアセンブルしてから、その命令のマシンコードを調べてください。おそらく、2つのレジスタ$1と$0がすぐに4で表示されます。

Mipsには、レジスター全体を1回のショットで即座に移動できるmov命令がありません。lui命令は、レジスタの上半分にビットを配置し、下半分にゼロを配置するために使用されます。Luiに続いてaddiまたはoriをチームとして使用して、即時にロードすることができます。または、上位ビットがゼロの場合、レジスタ0($ 0)のaddiまたはoriを使用して、単一の命令で下位ビットを設定できます。このasmがCコードを表すには、後者が当てはまる必要があります。

于 2012-11-01T05:47:32.733 に答える
1

私は次のことを推測しているMIPアセンブラーを知りません(Wiki記事MIPSアーキテクチャを読んだ後)

  1. ライターは、a = 0、したがって$ 1 = 0、したがってaddi $ 1、4は、swの準備ができている$ 1=4をxに設定することを知っています。
  2. NOPは意味がありません-命令が並列化されていることをライターが知っていない限り、クロックサイクル待機を挿入して、前の命令が完了したことを確認します。

コードにもっとコンテキストがありますか(つまり、xとa、bなどの設定)

于 2012-11-01T03:17:22.397 に答える
1

通常のMIPSアセンブラaddi $1,4は、の省略形ですaddi $1,$1,4。つまり、$1に4を追加します。定数をレジスタにロードする通常の省略形はli $1,4、アセンブラが通常に変換するものori $1,$0,4です。(レジスター$ 0には常にゼロが含まれます。)

a常にゼロであることがわかっていない限り、インストラクターの例は正しくないように見えます。その場合、このコードを実装するためのはるかに優れた方法があります。

于 2012-11-01T22:12:33.367 に答える