| Deadline | Friday, December 1, 11:59pm |
| Name on Marmoset | Q7 |
| To Submit |
height.asm
|
This is the third of several questions that will involve programming in MIPS assembly language.
To assemble your program (i.e., convert it into machine code)
you can use the course tool cs241.binasm.
You can then run the machine code program with one of our MIPS emulators:
mips.twoints, which takes two integers as input
and stores them in $1 and $2 before running the program.mips.stdin, which just runs the program with no
setup; this is intended for programs that work by reading from standard input.mips.array, which asks you to specify the elements of an array,
allocates the array in memory after the end of your program, stores the
starting address of the array in $1, and stores the number of elements in $2.
The following reference sheet describes all the instructions available in our simplified CS 241 dialect of MIPS assembly language.
In this problem, you will write a MIPS program that determines the height of a binary tree.
We use the convention that the height is the number of nodes in a path from the root to a leaf (not the number of edges, which is another common convention). Therefore, a single-node tree has height one.
The tree will be encoded in an array of 32-bit two's complement integers. Each node of the tree is encoded in three consecutive elements (words) of the array: a value stored at the node, a reference to the node's left child, and a reference to the node's right child. Each "reference" is either the array index where the child node is encoded, or -1 if the node is missing that child. For example, the following tree:
77
/ \
22 -8
/ \
-36 999
Could be encoded by following array:
A[0] = A[1] = A[2] = A[3] = A[4] = A[5] = A[6] = A[7] = A[8] = A[9] = A[10] = A[11] = A[12] = A[13] = A[14] = |
77 3 6 22 -1 -1 -8 9 12 -36 -1 -1 999 -1 -1 |
This tree has height 3.
Assume $1 holds the starting address of the array, and $2 holds the size of the array. Determine the height of the tree, store it in $3, and return.
A[0] = A[1] = A[2] = A[3] = A[4] = A[5] = A[6] = A[7] = A[8] = A[9] = A[10] = A[11] = A[12] = A[13] = A[14] = A[15] = A[16] = A[17] = |
77 6 3 -8 9 15 22 -1 -1 -36 -1 -1 241 241 241 999 -1 -1 |
If working on the Linux environment, it can be tedious to type in the arrays every time you run your program.
You can store different test inputs in different files and redirect them into mips.array. For example, you can create a file called array.txt with the following contents:
9 -1 3 -1 -1 6 -1 -1 -1 -1The first line is the size of the array, and the remaining lines are the elements of the array. This represents the following tree:
-1 / -1 \ -1You can test your program with this input as follows:
mips.array <(cs241.binasm < height.asm) < array.txtYou can create many of these input files to test your program with different inputs.
For debugging, you may find it useful to test your program with the stepper mips.stepper_twoints. Unfortunately, it doesn't support arrays as input, but you can work around this by creating a file that encodes the array in the following format:
beq $0, $0, debugArrayEnd debugArraySize: .word 9 debugArrayStart: ; list the array elements below .word 2 .word 3 .word 6 .word 4 .word -1 .word -1 .word 1 .word -1 .word -1 debugArrayEnd: lis $1 .word debugArrayStart lis $2 .word debugArraySize lw $2, 0($2)If you name this file
array.asm, you can run it with the stepper as follows:
mips.stepper_twoints <(cat array.asm height.asm | cs241.binasm)The program will skip over the array contents, then store the address of the array in $1 and the size of the array in $2, and then your MIPS program will run.
This problem is difficult. When you find a bug, try to find the smallest input that causes the bug so it is easier to trace the flow of the code. Other ideas for debugging include: