从递归汇编函数接收错误的输出

时间:2015-10-22 00:30:28

标签: assembly recursion mips towers-of-hanoi pcspim

我几天前在这里试图消除我对装配的一些无知,特别是MIPS中的寄存器。就像我上一篇文章一样,我将提出问题,我还在学习大会,而且我在大学课程。我不希望任何人做我的作业,我只需要一些温和的帮助来找到我的问题。从过去的经历来看,我有一种强烈的感觉,这是一个简单的解决方案,是当前的疏忽。我正在解决河内塔的问题,我知道我正好在完成它的边缘,因为给定N个盘,递归结构需要(2 ^ N)-1个移动来解决解决方案。问题是输出是不正确的,我知道它必须与我如何从不同的寄存器中移动值(钉的id)。经过4个半小时的摆弄,我正在寻找另一个人的视角。这是我目前的解决方案:

#############################################
#  $s0 - N discs                            #
#  $s1 - Origin Peg                         #
#  $s3 - Intermediate Peg                   #
#  $s2 - Destination Peg                    #
#  $t0 - Temp to hold an ID when swapping   #
#  $ra - for return                     #
#############################################

.data

firstHalfMsg:   .asciiz "Moving "
secondHalfMsg:  .asciiz " discs"
moveMsg:        .asciiz "move a disc: "
arrow:          .asciiz " -> "
endMsg:         .asciiz "End of process"
nwLn:           .asciiz "\n"

.text
.globl main

main:
        li $s0, 3           # Four Discs loaded into register s0 (N-discs)

        li $s1, 1           # ID for origin peg
        li $s2, 3           # ID for destination peg
        li $s3, 2           # ID for intermediate peg

        li $v0, 4
        la $a0, firstHalfMsg
        syscall                 
        li  $v0, 1              
        add $a0, $s0, $zero 
        syscall 
        li $v0, 4
        la $a0, secondHalfMsg
        syscall 
        li $v0, 4
        la $a0, nwLn    
        syscall 

        jal recHanoi        #start recursive call

        li $v0, 4
        la $a0, endMsg      #Load address for last output message
        syscall             #Display end message

        li $v0, 10
        syscall

recHanoi:
            subu $sp, $sp, 32       #reserve the stack
            sw $s0, 0($sp)
            sw $s1, 4($sp)
            sw $s2, 8($sp)
            sw $s3, 12($sp)
            sw $ra, 16($sp)


            subu $s0, $s0, 1
            move $t0, $s3
            move $s3, $s2
            move $s2, $t0

            li $v0, 4               #Start output messages
            la $a0, moveMsg 
            syscall 
            li  $v0, 1              # service 1 is print integer
            add $a0, $s1, $zero     # load desired value into argument register $a0, using pseudo-op
            syscall                 # print ID of origin peg    
            li $v0, 4
            la $a0, arrow       
            syscall             
            li  $v0, 1              # service 1 is print integer
            add $a0, $s3, $zero     # load desired value into argument register $a0, using pseudo-op
            syscall                 # print ID of destination peg
            li $v0, 4
            la $a0, nwLn    
            syscall                 #end output messages

            beq $s0, $zero, restore
            jal recHanoi

            move $t0, $s1
            move $s1, $s3
            move $s3, $t0 
            jal recHanoi            

restore:
            lw $s0, 0($sp)          #restore the stack
            lw $s1, 4($sp)
            lw $s2, 8($sp)
            lw $s3, 12($sp)
            lw $ra, 16($sp)
            addu $sp, $sp, 32

            jr $ra  

预期输出为:

     move a disc: peg 1 -> peg 3
     move a disc: peg 1 -> peg 2
     move a disc: peg 3 -> peg 2
     move a disc: peg 1 -> peg 3
     move a disc: peg 2 -> peg 1
     move a disc: peg 2 -> peg 3
     move a disc: peg 1 -> peg 3

实际输出是:

     move a disc: peg 1 -> peg 3
     move a disc: peg 1 -> peg 2
     move a disc: peg 1 -> peg 3
     move a disc: peg 2 -> peg 3
     move a disc: peg 3 -> peg 2
     move a disc: peg 3 -> peg 1
     move a disc: peg 2 -> peg 1

关于如何摆脱这个难题的任何提示或建议?除了做我目前正在做的事情之外,还有一个逻辑上的原因,这只是改变寄存器的值并希望它是正确的。那就不行了。

0 个答案:

没有答案