0

I was here a few days ago with an attempt to clear up some ignorance I had with assembly, specifically with registers in MIPS. Like my last post, I will preface my question with I'm still learning Assembly and I am in a University course. I don't expect anyone to do my homework, I just need some mild assistance in locating my problem. As from past experiences, I have a very strong feeling this is an easy fix that is a current oversight. I'm solving the Tower of Hanoi problem and I know I'm right on the edge of completing it as given N discs, the recursive structure takes (2^N)-1 of moves to solve the solution. Problem is the output is incorrect, and I know it has to with how I'm moving the values (id of the pegs) from the different registers. After 4 and half hours of fiddling around I'm seeking another's perspective. Here is my current solution:

#############################################
#  $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  

Expected Output is:

     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

Actual Output is:

     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

Any hints or suggestions on how I can move past this puzzle? There has to be a logical reason to this besides doing what I'm currently doing, which is just changing the values of the register and hope its right. That's going no where.

LumberSzquatch
  • 1,054
  • 3
  • 23
  • 46
  • 1
    The logical way is to 1) be clear about what you want each instruction to do and 2) use your debugger/simulator to step through the code and verify each one is really doing what you want. Since the very first printout is already wrong, it should be a simple matter to spot the error. – Jester Oct 22 '15 at 00:43
  • My thought process is that the move instructions before output calls simulate swapping the intermediate peg for the dest and the dest for the intermediate. And the same for the last one set of moves, except it now needs to be origin for destination and destination for origin. I added an extra set of moves after the branch to try and simulate my last statement but got pegs trying to move more than they had. Do you think I have the correct amount of move instructions and it's just a matter of looking more closely at the debugger to find solution? – LumberSzquatch Oct 22 '15 at 01:01
  • I can't reproduce your actual output using MARS. The first move is `1 -> 3`. – Michael Oct 22 '15 at 10:36
  • @Michael Ah, yeah, I just updated it. I put in the output I'm currently geting after I made changes but never updated the code. Up to date now. The first two moves should be correct. I'm still investigating though – LumberSzquatch Oct 22 '15 at 11:12
  • Really, my best advice is (optionally )take a brief break from it, then come back and step it through a debugger watching the registers/memory closely to see where your program's action differs from what you expect it to be. – Numeri Oct 22 '15 at 14:22
  • 1
    @Numeri That's sound advice. I know I'm over thinking it, so a break may be warranted. And to everyone else, I appreciate not giving a solution (honestly). It's a better learning experience to just have a nudge in the right direction. I'll go through the debugger again in an hour or so and see where it takes me, I'll post a solution once I find one just becuase. – LumberSzquatch Oct 22 '15 at 14:30
  • Of course, if you still can't find an answer, but manage to narrow the question down, that might help people here find the answer, as well! :) Good luck! – Numeri Oct 22 '15 at 14:33

0 Answers0