2012-03-31 24 views
1

アセンブリコードで何が間違っているのかよく分かりません。私は、いつか「メイン:」中に2つのヌルが$ A0、A1および$として入力された文字列を終了比較プログラムを書くためにしようとしている部分と、その後単純なMIPSアセンブリ

jal hamming 

は、プログラムを起動するために呼び出します。

基本的にこのセクションでは、1つの文字列がnull終端文字に当たるまで、2つの文字列をcharで比較する必要があります。その後、プログラムは停止し、終了するまでにいくつの文字が異なるかを返します。

私はそれが私が使っているジャンプと関係があると思いますが、私はあまりよく分かりません。私は私のプログラム私の出力ルックスを実行すると

diffchar: 
     li $t4, 0 
     li $t5, 1 

     beq $a0, $a1, samechars 
     move $v0, $t5 
     j diffcharend 

samechars: 
     move $v0, $t4 

diffcharend: 
     jr $ra 

hamming: 

absvaluedone: 
     li $a2, 0 
     #li $v0, 0 

     move $t0, $a0 
     move $t1, $a1 

hammingloopbegin: 
     lb $t2, 0($t0) 
     lb $t3, 0($t1) 
     beq $t2, $0, hammingdone 
     beq $t3, $0, hammingdone 

     la $a0, 0($t0) 
     la $a1, 0($t1) 
     jal diffchar **#this is the line that causes me problems, if I take this out it is fine** 
     beq $v0, $0, next 
     addiu $a2, $a2, 1 

next: 
     addiu $t0, $t0, 1 
     addiu $t1, $t1, 1 
     j hammingloopbegin 

hammingdone: 
     add $v0, $a2, $a3 
     jr $ra 

:プログラムは一種の長いので、私は(それゆえ、初期化され、すでに定義されているの$ A3、などの変数を無視する)の問題だと思うの主要部分を取っています言っ続ける無限ループのように:

Exception occurred at PC=0x00400144 
    Bad address in data/stack read: 0x10021226 
    Exception 7 [Bad address in data/stack read] occurred and ignored 
Exception occurred at PC=0x00400140 
    Bad address in data/stack read: 0x1002121b 
    Exception 7 [Bad address in data/stack read] occurred and ignored 

私はdiffcharまたは私がdiffcharために周りにジャンプするために使用するプロセスと間違って何かがあると思います。これは私の初めてのアセンブリコードの記述です。だから私は本当に基本的な何かを考えています。どのポインタも素晴らしいでしょう。ヘルプ

答えて

2

ため

おかげであなたはjal diffchar前にリターンアドレスを保存しないでください。それが返され、$raはまだ新しい値を保持しています。 jr $rahammingdoneに再度入力すると、diffcharコールの直後にジャンプします。 diffcharを呼び出す前に$raをどこかに格納し、呼び出しが復帰した後に復元する必要があります。ここで

が発生している問題とランタイム・スタックを使用してソリューションを説明good explanation of nested procedures in MIPS、次のとおりです。

jal B命令を実行すると、手順Aのためのレジスタ $raで戻りアドレスが上書きされます プロシージャBの戻りアドレスで、プロシージャBは正しくAに戻りますが、 プロシージャAがjr命令を実行すると、jal Bの後の次の命令であるBの戻りアドレス に再び戻りますプロシージャーA.プロシージャーAを無限ループに入れます。

...

システムスタックは、一般的にリターンアドレスを保存するために使用されます。プロシージャが呼び出されたときに をスタックにプッシュすると、 に戻り、復帰命令を実行できます。次のコードは、スタックの最上部からの戻りアドレスをポップし、レジスタの 戻りそれを

sw  $ra, ($sp) 
    add  $sp, -4 

:レジスタ$ra

リターンアドレスは、次のMALコードでシステムスタック にプッシュすることができます$ra

add  $sp, 4 
    lw  $ra, ($sp)