0

几天前我来到这里,试图澄清我对汇编的一些无知,特别是在 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

关于如何克服这个难题的任何提示或建议?除了做我目前正在做的事情之外,这必须有一个合乎逻辑的理由,这只是改变寄存器的值并希望它是正确的。那是无处可去。

4

0 回答 0