Mips Needleman 递归

Mips Needleman Recursion

对于我的大学,我必须在 Mips 汇编中编写一个特定的 Needleman 算法:

我希望我快完成了,但是,我还有一个大问题:当我运行它的时候,它不会停止并且"rotates"放在最后几个字母上。

我认为我的分支是正确的,我的堆栈分配有问题,但我不知道如何解决,我几乎尝试了将近一周,只剩下一周了。

所以我希望你能帮助我解决我的问题。

.data

word1: .asciiz "teflon"
word2: .asciiz "telefon"
newLine: .asciiz "\n"

.text
.globl main

# $a0 : word 1
# $a1 : word 2
# returns via $v0 : best alignment score
#s0- current word1-char , s1- current word2-char , s2-word1-length, s3-word2-length,s5-recursion-counter,t2-temporary-result, 
#t3-temporary-result, t4-temporary-result


needleman_wunsch:

    # Fuegen Sie Ihren Code zum Beispiel hier ein.
    # Auch der restliche Inhalt dieser Datei darf 
    # von Ihnen nach Belieben angepasst werden.
    add  $v0,[=10=],[=10=]          #result=0
    add  $s5,[=10=],[=10=]          #counter=0 
    add  $t2,[=10=],[=10=]          #result1=0 
    add  $t3,[=10=],[=10=]          #result2=0 
    add  $t4,[=10=],[=10=]          #result3=0 

rekursionsadresse:

    addi $s5,$s5,1          #counter++ 
    #addi $a0,$a0,1         #$s0=&word1[i] 
    #addi $a1,$a1,1         #$s1=&word2[j]
    lb   $s0,0($a0)         #$s0=word1[i] 
    lb   $s1,0($a1)         #$s1=word1[j]
    add  $t0,$a0,[=10=]         #save $a0 in $t0
    add  $t1,$v0,[=10=]         #save $v0 in $t1 

#   move $a0,$s0            #load string adress in to $a0
#   li   $v0,11             #load syscall for string printing 
#   syscall                 #print string 
#   move $a0,$s1            #load string adress in to $a0
#   syscall                 #print string
#   move $a0,$t1            #load current result into $a0
#   li   $v0,1              #load syscall to integer printing 
#   syscall                 #print current result 
    move $a0,$s5
    li   $v0,1 
    syscall                 #print counter 
#   la     $a0, newLine
#   addi   $v0, [=10=], 4
#   syscall

    move $a0,$t0            #restore $a0
    move $v0,$t1            #restore $v0 
    move $t1,$a1            #store $a1

    move $a0,$t0            #restore $a0 
    move $a1,$t1            #restore $a1

    beqz $s0,if10           #if |word1| == 0 goto if10 
    beqz $s1,if01           #if |word2| == 0 goto if01 ; case |word1| >=1 and |word2|>=1 



#calculate result1 (score(word1[i+1],word2[j+1])+eq(word1[0],word2[0])) 

    addi $sp,$sp,-12        #stackreservation for 3 values
    sw   $ra,8($sp)         #save $ra on stack 
    sw   $a1,4($sp)         #save $a1 on stack 
    sw   $a0,0($sp)         #save $a0 on stack

    addi $a0,$a0,1          #get next character
    addi $a1,$a1,1          #get next character
    jal  rekursionsadresse  #$v0=score(word1[i+1],word2[j+1])

    lw   $a0,0($sp)         #load $a0 from stack 
    lw   $a1,4($sp)         #load $a1 from stack
    lw   $ra,8($sp)         #load $ra from stack
    addi $sp,$sp,12         #restore stackpointer
eq:
    lb   $s0,0($a0)         #load current character from word1
    lb   $s1,0($a1)         #load current character from word2
    bne  $s0,$s1,neq        #if chars are not equal goto not equal (neq) 
    addi $v0,$v0,4          #increase result by 4  
    j   marker              #jump to marker  
neq: 
    addi, $v0,$v0,-2        #decrease result by 2  

marker:

    move $t2,$v0            #store return result1 


#calculate result2 (score(word1[i],word2[j+1])-3)   


    addi $sp,$sp,-12        #stackreservation for 3 values
    sw   $ra,8($sp)         #save $ra on stack 
    sw   $a1,4($sp)         #save $a1 on stack 
    sw   $a0,0($sp)         #save $a0 on stack

    addi $a1,$a1,1          #get next character 
    jal  rekursionsadresse  #$v0=score(word1[i],word2[j+1])
    addi $v0,$v0,-3         #$v0=score(word1[i],word2[j+1])-3

    lw   $a0,0($sp)         #load $a0 from stack 
    lw   $a1,4($sp)         #load $a1 from stack
    lw   $ra,8($sp)         #load $ra from stack
    addi $sp,$sp,12         #restore stackpointer
    move $t3,$v0            #save result3

#calculate result3 (score(word1[i+1],word2[j])-3)   


    addi $sp,$sp,-12        #stackreservation for 3 values
    sw   $ra,8($sp)         #save $ra on stack 
    sw   $a1,4($sp)         #save $a1 on stack 
    sw   $a0,0($sp)         #save $a0 on stack 

    addi $a0,$a0,1          #word1-index i +=1
    jal  rekursionsadresse  #$v0=score(word1[i+1],word2[j])
    addi $v0,$v0,-3         #$v0=score(word1[i+1],word2[j])-3 

    lw   $a0,0($sp)         #load $a0 from stack 
    lw   $a1,4($sp)         #load $a1 from stack
    lw   $ra,8($sp)         #load $ra from stack
    addi $sp,$sp,12         #restore stackpointer
    move $t4,$v0            #save result3


#compare the 3 results 
    bgt  $t2,$t3,ifmax      #if result1 > result2 goto max3
    bgt  $t4,$t3,max3       #if result3 > result2 goto max3 
    move $v0,$t3            #store biggest result in $v0 
    jr   $ra                #return to needleman_wunsch
ifmax:  
    bgt  $t4,$t2,max3       #if result3 > result1 goto max3
    move $v0,$t2            #store biggest result in $v0 
    jr   $ra                #return to needleman_wunsch
max3: 
    move $v0,$t4            #store biggest result in $v0 
    jr   $ra                #return to needleman_wunsch


if01:                       #case |word1| >=1 and |word2|==0    
    addi $sp,$sp,-12        #stackreservation for 3 values
    sw   $ra,8($sp)         #save $ra on stack 
    sw   $a1,4($sp)         #save $a1 on stack 
    sw   $a0,0($sp)         #save $a0 on stack

    addi $a0,$a0,1          #get next character
    jal  rekursionsadresse  #$v0=score(word1[i+1],word2[j])
    addi $v0,$v0,-3         #$v0=score(word1[i+1],word2[j])-3 

    lw   $a0,0($sp)         #load $a0 from stack 
    lw   $a1,4($sp)         #load $a1 from stack
    lw   $ra,8($sp)         #load $ra from stack
    addi $sp,$sp,12         #restore stackpointer
    jr   $ra                #jump back to last method  

if10:                       #case |word1| == 0 
    beqz $s1,if11           #if |word2|==0 goto if1.1 ;case |word1| ==0 and |word2|>=1 

    addi $sp,$sp,-12        #stackreservation for 3 values
    sw   $ra,8($sp)         #save $ra on stack 
    sw   $a1,4($sp)         #save $a1 on stack 
    sw   $a0,0($sp)         #save $a0 on stack

    addi $a1,$a1,1          #get next character
    jal  rekursionsadresse  #$v0=score(word1[i],word2[j+1])
    addi $v0,$v0,-3         #$v0=score(word1[i],word2[j+1])-3

    lw   $a0,0($sp)         #load $a0 from stack 
    lw   $a1,4($sp)         #load $a1 from stack
    lw   $ra,8($sp)         #load $ra from stack
    addi $sp,$sp,12         #restore stackpointer
    jr   $ra                #jump back to last method

if11:                       #case |word1| ==0 and |word2|==0
    add  $v0,[=10=],[=10=]          #return 0 
    jr   $ra                #jump back to last method 




main:
    addi $sp, $sp, -4
    sw $ra, 0($sp)

    la $a0, word1
    la $a1, word2
    jal needleman_wunsch

    # Geben Sie auf jeden Fall den Score auf der
    # Konsole aus.
    addi $a0, $v0, 0
    li $v0, 1
    syscall

    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra

你找到解决办法了吗? 也许这不是必需的:

move $a0,$t0            #restore $a0
move $v0,$t1            #restore $v0 
->move $t1,$a1            #store $a1

move $a0,$t0            #restore $a0 
->move $a1,$t1            #restore $a1

为什么将$a1 存储在$t1 中并在两行后恢复它?

抱歉没有这么快回答。 我找到的解决方案(在朋友的帮助下)是将 return 结果存储在一个额外的寄存器中,例如 $t2.