2017-11-09 3 views
0

これを見て、アドレスを印刷するのに数時間を費やしてしまいました。これは、QTSpimで実行される簡単なアセンブリプログラムです。プログラムは、配列の中で最小の2つの整数を見つけ出し、配列の直後の位置のメモリに格納されたmainに追加して返します。MIPSデータ/スタックの読み込みに不良アドレスがあります

プログラムは配列の20個の値を取りますが、次にデータ/スタック読み取り値0x10040000の不良アドレスを計算して吐き出します。他のすべてのデータは0x100100XXのメモリ位置にあります。なぜ40000が登場するのかわかりません。

.data 
Fresh: .space 80 
freshSmallestSum: space 4 

.text 
sumMin: 
    lw  $t2, 0($a0) # $t2 = smallest array[i] 
    addi $t4, $t0, 1 # $t4 = i + 1 
    sll  $t4, $t4, 2 # $t4 = i * (2^2) 
    add  $t4, $t4, $a0 # $t4 = absolute address array[i+1] 
    lw  $t3, 0($t4) # $t3 = array[i+1] 
    li  $t4, 2  # i = 2 
    ble  $t2, $t3, loopSmall # if $t2 <= t3 jump 
    move $t9, $t2 
    move $t2, $t3 
    move $t3, $t9 
loopSmall: 
    bge  $t4, $t1, ret1 
    sll  $t5, $t4, 2 # $t5 = i * (2^2) 
    add  $t5, $t5, $a0 # absolute address array[i] 
    lw  $t5, 0($t5) # $t5 = array[i] 
    ble  $t3, $t5, next2 # if $t3 <= array[i], jump 
    move $t3, $t5 # else $t3 = array[i] 
    ble  $t2, $t3, next2 # if $t2 <= $t3, jump 
    move $t9, $t2 # else swap two smallest 
    move $t2, $t3 
    move $t3, $t9 
next2: 
    addi $t4, $t4, 1 # i++ 
    j loopSmall 
ret1: 
    add  $v0, $t2, $t3 # $v0 = smallest + secondSmallest 
    jr  $ra 

.text 
.globl main 
main: 
    li  $t3, 0 
    li  $t0, 0  # i = 0 
    li  $t1, 20  # $t1 = 20 
    la  $s2, Fresh 

inLoop: 
    bge $t3, $t1, next # If $t3 > array length, jump 
    sll  $t2, $t3, 2 
    add  $t4, $t2, $s2 # Absolute address of fresh 
    li  $v0, 5 
    syscall 
    sw  $v0, 0($t4) 
    addi $t3, $t3, 1 # Increment counter 
    j  inLoop  
move  $a0, $s2 # $a0 = address Fresh 
    jal  sumMax  # Get max sum of Fresh 
    la  $t1, freshLargestSum 
    sw  $v0, 0($t1) # Store sum in freshLargestSum 

    move $a0, $s2 
    jal  sumMin  # Get min sum of Fresh 
    la  $t1, freshSmallestSum 
    sw  $v0, 0($t1) # Store sum in freshSmallestSum 

exit:  li $v0, 10 
    syscall 
+0

シミュレータを使用してコードをシングルステップで実行し、どの命令がフォルトしているかを確認します。その後、レジスタの値をチェックして悪い点を見つけ、次に悪い点がどのようになっているかを確認するために逆方向に作業します。 PS:私はラベル「次へ」、コピー・ペースト・エラーを見つけることさえできないか、本当にそれを持っていませんか?また、 'sumMin'は' $ t1'の配列サイズを期待しているようですが、その時点で 'freshLargestSum'のアドレスを含んでいます。 – Jester

+0

申し訳ありませんが、間違いなくコピー貼りエラーです。プログラムはこのコードセグメントよりもはるかに長くなっています。関連する部分のみをカットしようとしています。 $ t1はエラーだった!ありがとうございました - ほとんどのレジスタの変更はsumMinのコードには近似していませんでしたので、私はそれをキャッチしませんでした。あなたのコメントで固定された未来の凝視の時間、ありがとう! – Tenze

+0

特に初心者の方は、デバッグのために実際に投稿しているコードをテストしてください。 –

答えて

1

ここのコードのほとんどは素晴らしいようですが、これは完全なファイルではありませんか?

あなたのsumMin関数は配列サイズをt1として求めていますが、それはfreshLargestSumアドレスを与えていますか?

コードを1行ずつ進めてみましたか? 特にMIPSでは、大抵のエラーは後でコードで必要とする上書きレジスタです。特に私たちが飛び降りるときに。

優れたデバッグ手法は、すべての機能が期待どおりに機能することをテストすることです。そうであれば、エラーはメインコードにあることがわかります。とに関係する可能性がある:リターンを上書き間違った場所に

  • 上書きされたレジスタ
  • JAL
  • 誤ったロジックを登録

うまくいけば、これはあなたの問題を解決するのに役立ちます!

関連する問題