Lab 6 - Calling Conventions

CS 3410 Spring 2017

Due: Upload your implementation of the Iterative and/or Recursive Hailstone by 11:59pm on Monday, March 13, 2017

Optional: If you upload your memoized version, we will run it through the auto-grader, too.

(Only the highest of the iterative, recursive, or memoized scores counts for this lab grade, but all three versions will be turned in again and graded again as part of your next project, so it is in your best interests to get feedback early on.)


In this lab you will re-visit the hailstone programs that you worked on in a previous project.

A hailstone sequence is defined as follows: start at any positive integer n; if n is even, divide it by 2 to get n/2; else triple it and add one to get 3n+1; then repeat with the new number. You will implement the hailstone function, which counts how many steps it takes for the hailstone sequence to converge to 1 from a given starting point. For instance, hailstone(40) returns 8 because the sequence starting at 40 converges in 8 steps: 40, 20, 10, 5, 16, 8, 4, 2, 1. And hailstone(31) returns 106 due to its long and chaotic sequence: 31, 94, 47, 142, 71, 214, ..., 3077, 9232, 4616, 2308, 1154, 577, ..., 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1.

There are several ways to compute the hailstone function. You will implement one (optionally, more) of the methods below (please do not submit MIPS code with any form of main function).

Implement the iterative, recursive and memoized versions of the hailstone function using MIPS assembly code. They must all work on your processor in Logisim, though you will have be careful when testing to selecting starting values that converge in a reasonable time.

Testing and input for hailstone functions

Your hailstone functions are just that: functions. They should get their inputs from registers $a0 and $a1 and they should return their results via register $v0. To test the functions, you will nead to create a "main" program which initializes the stack (by setting $sp and $fp to something reasonable and usable), puts some input in the argument registers, then calls the function via JAL. The hailstone functions never make system calls or any other function calls that could possibly read input from the user. Your main program could if you managed to wire up a keyboard though.

For the interested student

It is an open question whether all starting points eventually converge to 1 or not. The Collatz conjecture states that all positive integers converge to 1, but this isn't yet proven. For this project, you can assume all numbers converge — if you find one that doesn't you get an automatic A for the project. You can watch this video or find links to more reading on the Wikipedia page for the Collatz conjecture.

MIPS (subset) Assembly Syntax

The MIPS Program ROM component has a built-in assembler that understands all of the instructions you will implement. The syntax is standard MIPS syntax. Labels are case sensitive, everything else ignores case. Anything following a pound ('#') is a comment. In this project, you will only use a few of the instructions listed here.

The instruction syntax is the same as given in the MIPS standard (and different from the output of gcc and many other tools). Registers are written as $0, $1, ..., $31, and the destination register goes on the left, followed by source registers and immediate values on the right. Most integer arguments (immediates, shift amounts, jump targets) can be specified in hex (i.e. 0x12ab), in decimal (i.e. 1234 or -1234), a label, or the special constant PC. The assembler will replace PC with the address of the instruction itself. Most constants have some restrictions: jump destinations must have the same upper 4 bits as the PC+4, and must be a multiple of 4; branch destinations must be a multiple of 4 and fit in a signed 18 bit immediate; etc. As a special case, when a branch target is specified symbolically as a label, the assembler will automatically subtract the current PC value to obtain a signed offset.

By default, the first instruction will be placed at address 0, and subsequent instructions are placed at at addresses 4, 8, 12, etc.

Assembler directives. The Program ROM assembler understands two standard MIPS assembler directives, .text and .word, both of which take integer (hex or decimal) arguments. For example, .text 0x50000000 will direct the assembler to place subsequent instructions starting at address 0x50000000. And .word 0x24030005 directs the assembler to use the value 0x24030005 as the next machine instruction, which happens to be the machine code for ADDIU $3, $0, 5.

Symbolic register names. The assembler built into the MIPS Program ROM accepts standard MIPS register names: $zero, $at, $v0, $v1, $a0 - $a4, $s0 - $s7, $t0 - $t9, $k0, $k1, $sp, $gp, $fp, and $ra.

Some examples of instructions are:

Immediate Arithmetic ADDIU $12, $0, PC
Register Arithmetic ADDU $13, $0, $20
Immediate Load LUI $14, 0x123
Shifts SLL $13, $13, 2
SLLV $15, $14, $3
Jumps J 0x24
J my_label
JR $5
JALR $31, $5
Branches BEQ $5, $6, -12
BEQ $5, $6, my_loop_top
BLEZ $9, 16
BLEZ $9, my_loop_done
Memory Load/Store LW $12, -4($30)
SW $12, 0($30)