2017-09-30 89 views
-1

CプログラムをMIPSアセンブリプログラムに変換しようとしています。以下は、プログラムのための私のCコードです:(注意:電球[番号]は、ユーザが入力した「数」のために、すべてのゼロ値に初期化配列である)CプログラムをMIPSアセンブリ言語プログラムに変換する

for(int i = 1; i <= number; i++) 
      for(int j = 1; j <= number; j++) 
       if(j % i == 0) 
        Bulbs[j-1] = (Bulbs[j-1] + 1) % 2; 

次のように私はこれまで持っていることです:

li $t0, 0     #$t0 is set to 0 to be used as index for for loop1 
li $t1, 0     #$t1 is set to 0 to be used as index for for loop2 

li $s2, 4     #integer 4 is stored in s2 
mult $s3, $s2    #input number($s3) is multiplied by 4 
mflo $s4     #result of multiplication is stored in $s4 

loop1: 
bgt $t0, $s4, end_loop1  #if t$0 > $s4(input number*4), exit loop1, 
          #performing multiplication by 4 since word occupies 4 bytes 
addi $t3, $t3, 1    #t3 is initialized to serve as "i" from for loop1 
loop2: 
    bgt $t1, $s4, end_loop2 #if $t1 > (input number*4), exit loop2 
    addi $t4, $t4, 1   #t4 is initialized to serve as "j" from for loop2 
    div $t4, $t3 
    mfhi $t5    #$t4 % $t3 is stored in $t5 
    bne $t5, $zero, if_end #checking for if condition 

    if_end: 
    addi $t1, $t1, 4  #increment $t1 by 4 to move to next array element 
    j loop2     #jump back to top of loop2 

end_loop2: 
addi $t0, $t0, 4   #increment $t0 by 4 
j loop1      #jump back to the top of loop1 

end_loop1: 

私は私のforループの実装の作品を考えると、私は、ifの条件を正確に設定アップを(私が間違っているなら、私を修正)持っているが、私は「球根[J-を実装する方法がわかりません1] =(球根[j-1] + 1)%2; '私の条件付きの後の行。私はMIPSを初めて使い、どんな助けやフィードバックも感謝しています!

+4

"Cコードをアセンブリコードに変換するのは、*コンパイラ*の作業ではありませんか? ;) –

+4

このコンバーターは「コンパイラー」と呼ばれ、99.99%の人間のコンバーターよりはるかに優れています。 https://godbolt.org/g/CPZtob –

+0

こんにちは@ PeterJ_01、これは多くの意味があります。しかし、$ LFB24 =のような行は何をしますか? $ LBB5 =となります。 ? –

答えて

0

Bulbsがどこかの配列として定義されているとします。

la $t7, Bulbs # Move base pointer of bulbs to $t7 
add $t7, $t7, $t1 # $t7 = &Bulbs[j] 
lw $t6, -4($t7) # $t6 = Bulbs[j - 1] 
addi $t6, $t6, 1 # $t6 = Bulbs[j - 1] + 1 
andi $t6, $t6, 1 # $t6 = (Bulbs[j - 1] + 1) % 2 
sw $t6, -4($t7) # Bulbs[j - 1] = $t6 

これはthis informationに基づいています。そして、

Bulbs[j-1] = (Bulbs[j-1] + 1) % 2; 

は次のように変換する必要があります。私は前にMIPSアセンブリをやったことはありませんが、それはRISCなので、どれほど難しいでしょうか? :)

ところで、アセンブリの翻訳にバグがあるようです。 Cバージョンではjは1から始まりますが、アセンブリバージョンでは0から始まるようです($t1配列インデックスは2行目で0に初期化され、ループ本体の後まで変更されません)。修正は簡単です - 0ではなく4に初期化してください。

+2

あなたは冗談か? 'rem'ハードウェア除算を2の定数除数にする? (https://stackoverflow.com/questions/40354978/why-is-this-c-code-faster-than-my-hand-written-assembly-for-testing-the-collat​​/40355466#40355466)。それとも、アセンブラが 'AND'になる疑似命令ですか?私たちは '電球[j-i]'が非負であることを知っています。 –

+0

@PeterCordes良いコメント - それは非常に小さな返信応答だった。 (x&0x1)としてすぐに最適化(x%2)するのに十分なアセンブラを書かなかったのですが、それはかなり明白です。しかし、最終的には、差異は、とにかく(remとは対照的にdivと+との比較で)1つの命令でなければならない。それはひどいものではない。 – K4rolis

+2

すべての命令が同じ速度で実行されるわけではありません。現代のx86では、 'div 'は'と '(1サイクル)より約30倍高い待ち時間です。何かあれば、高性能ハードウェアディバイダは(シリコンダイ領域では)高価なので、おそらくMIPSでは悪化します。ディビジョンが遅い、コンパイラよりも優れたコードを作るために何をしているかを知る方法については、私がリンクしている答えをご覧ください。 (ただし、そうしているとしばしばできる。) –

関連する問題