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.