Chapter 1: Q10E (page 2)
A.10 [10] <§§A.6, A.9> Using SPIM, write and test a recursive program for solving the classic mathematical recreation, the Towers of Hanoi puzzle. (This will require the use of stack frames to support recursion.) The puzzle consists of three pegs (1, 2, and 3) and n disks (the number n can vary; typical values might be in the range from 1 to 8). Disk 1 is smaller than disk 2, which is in turn smaller than disk 3, and so forth, with disk n being the largest. Initially, all the disks are on peg 1,
Starting with disk n on the bottom, disk n − 1 on top of that, and so forth, up to disk 1 on the top. The goal is to move all the disks to peg 2. You may only move one disk at a time, that is, the top disk from any of the three pegs onto the top of either of the other two pegs. Moreover, there is a constraint: You must not place a larger disk on top of a smaller disk.
The C program below can be used to help write your assembly language program.
/* move n smallest disks from start to finish using
extra */
void hanoi(int n, int start, int finish, int extra){
if(n != 0){
hanoi(n-1, start, extra, finish);
print_string(“Move disk”);
print_int(n);
print_string(“from peg”);
print_int(start);
print_string(“to peg”);
print_int(finish);
print_string(“.\n”);
hanoi(n-1, extra, finish, start);
}
}
main(){
int n;
print_string(“Enter number of disks>“);
n = read_int();
hanoi(n, 1, 2, 3);
return 0;
}
Short Answer
The corresponding MIPS assembly language program:
Call Hanoi(4, 1, 3):
mov r0, #3
push {r0}
mov r0, #1
push {r0}
mov r0, #4
push {r0}
Call Hanoi(4, 1, 3)
bl Hanoi
add sp, sp, #12
Hanoi:
push {lr}
push {fp}
mov fp, sp
sub sp, sp, #4
ldr r0, [fp, #8]
cmp r0, #1
bne else
movw r0, #:lower16:Str
movt r0, #:upper16:Str
ldr r1, [fp, #12]
ldr r2, [fp, #16]
bl printf
b ifEnd
else:
ldr r0, [fp, #12]
rsb r0, r0, #6
ldr r1, [fp, #16]
sub r0, r0, r1
str r0, [fp, #-4]
ldr r0, [fp, #-4]
push {r0}
ldr r0, [fp, #12]
push {r0}
ldr r0, [fp, #8]
sub r0, r0, #1
push {r0}
Call Hanoi(ndisk-1, fromPeg, helpPeg)
bl Hanoi
add sp, sp, #12
movw r0, #:lower16:Str
movt r0, #:upper16:Str
ldr r1, [fp, #12]
ldr r2, [fp, #16]
bl printf
ldr r0, [fp, #16]
push {r0}
ldr r0, [fp, #-4]
push {r0}
ldr r0, [fp, #8]
sub r0, r0, #1
push {r0}
Call Hanoi(ndisk-1, fromPeg, helpPeg)
bl Hanoi
add sp, sp, #12
ifEnd:
mov sp, fp
pop {fp}
pop {pc}
.data