Question 6

Deadline Friday, November 3, 11:59pm
Name on Marmoset Q6
To Submit print.asm

MIPS Assembly Programming, Part II

This is the second 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:

In this question, you will use the output feature of MIPS assembly language. If you store (with sw) to the special address 0xffff000c, MIPS will take the least significant byte (rightmost 8 bits) of the source register and write this byte to standard output.

MIPS Assembly Language Reference

The following reference sheet describes all the instructions available in our simplified CS 241 dialect of MIPS assembly language.

Printing Decimal Numbers

Write a MIPS procedure called print which takes a 32-bit two's complement number as a parameter in $1 and prints the base 10 representation of the number in ASCII, followed by a line feed (ASCII code 0x0A).

Your procedure must preserve the values of all general-purpose registers.

This question is, in some sense, the reverse of Question 5. This time, you are going from a value in a register to a base 10 number formatted in ASCII.

Clarifications
Output Example & Testing Tips

Here are two ways to test your procedure.

The following program is meant to be used with mips.array. It loops over the array and calls print on each element, which lets you easily test your procedure with many numbers at once.

lis $5
.word print
lis $11
.word 1
lis $4
.word 4
add $10, $1, $0
sw $31, -4($30)
sub $30, $30, $4
mainProgramLoop: 
  beq $2, $0, mainProgramEnd
  lw $1, 0($10)
  jalr $5
  sub $2, $2, $11
  add $10, $10, $4
  beq $0, $0, mainProgramLoop
mainProgramEnd:  
add $30, $30, $4
lw $31, -4($30)
jr $31
You can manually place your print procedure at the end of the file for testing, or combine them with cat. You may wonder why were are combining the files this way rather than using linking. The answer is just that linking the files requires extra steps and would make testing slightly more awkward. Assuming that array.asm contains the above program, and print.asm contains your print procedure, here is a single line to assemble and run the combined program, using Bash's process substitution feature. You will be asked to enter the size of the array and the number of elements.
mips.array <(cat array.asm print.asm | cs241.binasm)
Enter length of array: 3
Enter array element 0: -1
Enter array element 1: 241
Enter array element 2: 1000
Running MIPS program.
-1
241
1000
MIPS program completed normally.
$01 = 0x000003e8   $02 = 0x00000000   $03 = 0x00000000   $04 = 0x00000004
$05 = 0x00000048   $06 = 0x00000000   $07 = 0x00000000   $08 = 0x00000000
$09 = 0x00000000   $10 = 0x00000144   $11 = 0x00000001   $12 = 0x00000000
$13 = 0x00000000   $14 = 0x00000000   $15 = 0x00000000   $16 = 0x00000000
$17 = 0x00000000   $18 = 0x00000000   $19 = 0x00000000   $20 = 0x00000000
$21 = 0x00000000   $22 = 0x00000000   $23 = 0x00000000   $24 = 0x00000000
$25 = 0x00000000   $26 = 0x00000000   $27 = 0x00000000   $28 = 0x00000000
$29 = 0x00000000   $30 = 0x01000000   $31 = 0x8123456c
Notice each array element is printed on its own line in between Running MIPS program and MIPS program completed normally.

Alternatively, you can hardcode the array in your program. In this program, the array [241, 242, 243] is hardcoded after the main program. This is a bit more work to set up, but the advantage of this is that it lets you use the tool mips.stepper_twoints, which lets you step through your code line by line to help with debugging.

lis $10
.word mainProgramArray
lis $2
.word mainProgramEndArray
lis $5
.word print
lis $4
.word 4
sw $31, -4($30)
sub $30, $30, $4
mainProgramLoop: 
  beq $10, $2, mainProgramEnd
  lw $1, 0($10)
  jalr $5
  add $10, $10, $4
  beq $0, $0, mainProgramLoop
mainProgramEnd:  
add $30, $30, $4
lw $31, -4($30)
jr $31
mainProgramArray:
.word 241
.word 242
.word 243
mainProgramEndArray: