Assignment 3

6 minute read

Due: by the end of the calendar day on Wednesday, September 24, 2025

A Python program with functions and arrays

The following Python program builds a histogram for an array of data values between 0 and 99. It is spread across four different functions.

# returns the 10s digit of a two-digit number
def tens_digit(x):
    return x // 10

# for each item in the data array, looks at its tens digit d
# and increment hist[d]
def build_hist(data, n, hist):
    i = 0
    while i < n:
        d = tens_digit(data[i])
        hist[d] = hist[d] + 1
        i += 1

# prints the digit and a number of * equal to length argument
def print_bar(digit,length):
    i = 0
    print("\n",digit,"0s ",sep="",end="")
    while i < length:
        print("*", end="")
        i += 1
    print()

def main():
    # how many data items we'll have
    data_len = 50
    # data we want to make into a histrogram by which digit is in the tens position
    data = [0, 60, 23, 36, 5, 0, 43, 42, 48, 32, 0, 66, 65, 62, 28, 32, 53, 5, 98, 15, 47, 50, 24, 40, 0, 57, 43, 42, 25, 32, 48, 30, 40, 61, 8, 55, 16, 61, 0, 99, 91, 31, 81, 54, 47, 79, 39, 78, 44, 63]
    # hist is an array for counting how many time we see each digit in the tens position
    hist = [0,0,0,0,0,0,0,0,0,0]
    build_hist(data, data_len, hist) 

    # print a bar for each digit
    i = 0
    while i < 10:
        print_bar(i,hist[i])
        i += 1

main()

Here’s the output you get when you run it in the console. Notice that it prints each tens digit and then a number of * characters reprenting how many of the data items had that tens digit.

00s ********

10s **

20s ****

30s *******

40s ***********

50s *****

60s *******

70s **

80s *

90s ***

A start to translating the Python program into MIPS

Here’s an attempt to translate the program into MIPS. The main, tens_digit, and print_bar procedures are finished, but you will need to finish implementing the build_hist procedure.

# =========================================
# Your Name:
#
# Histogram by tens digit, Python to MIPS translation
#   of four functions: tens_digit, build_hist, print_bar, main
#
# =========================================

.data
# Input data (50 elements)
data:		.word 0, 60, 23, 36, 5, 0, 43, 42, 48, 32,
  		0, 66, 65, 62, 28, 32, 53, 5, 98, 15,
  		47, 50, 24, 40, 0, 57, 43, 42, 25, 32,
  		48, 30, 40, 61, 8, 55, 16, 61, 0, 99,
  		91, 31, 81, 54, 47, 79, 39, 78, 44, 63
data_len:	.word 50

# Histogram (10 zeros)
hist:		.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

# Strings / chars
newline:	.asciiz "\n"
label_0s:	.asciiz "0s "
star_char:	.asciiz "*" 

.text

########################
# main:
#   - call build_hist(data, data_len, hist)
#   - for each digit in 0..9 calls print_bar(digit, hist[digit])
########################
main:
	# Build histogram
	la $a0, data
	lw $a1, data_len
	la $a2, hist
	jal build_hist

	# Loop digit, i = 0..9
	li $t0, 0 # i = 0
main_loop:
	slti $t4, $t0, 10 # check i < 10
	beq $t4, $zero, main_end # branch if the check fails

	# a0 = i
	move $a0, $t0

	# a1 = hist[digit]
	sll $t1, $t0, 2 # digit * 4
	la $t2, hist 	# start of the hist array
	add $t3, $t2, $t1 # calculating address of hist[digit]
	lw $a1, 0($t3)	# load value of hist[digit] into $a1

	# call print_bar(digit, hist[digit])
	jal   print_bar

	addi $t0, $t0, 1 #increment loop counter
	b main_loop

main_end:
	# Exit program
	li $v0, 10
	syscall

########################
# def tens_digit(x):
#return x // 10
#
# $a0: x - the two-digit value to find the tens digit of
#
########################
tens_digit:
	li $t0, 10
	div $a0, $t0 # results of division and multiplication end up in a special register called hi and lo
	mflo $v0	# this instruction moves out of the lo register into another register, $v0 in this case
	jr $ra # return

########################
# def build_hist(data, n, hist):
#i = 0
#while i < n:
#d = tens_digit(data[i])
#hist[d] = hist[d] + 1
#i += 1
#
# $a0: the address of the data array
# $a1: n - the number of items in the data array
# $a2: the address of the hist array
#
########################
build_hist:
# put your code here
	# things to do
	#	- translate the code from the build_hist python function
	#	- make a call to the tens_digit function
	#	- for full credit, preserve needed registers by utilizing the stack
	#		- you must restore $ra and any $s_ registers to what they were originally before you return
	#		- you have to assume any $t_, $a_, or $v_ registers you need will be changed by functions you call
	#			- save them before making a call to tens_digit and restore them afterwards (using either $s_ registers or the stack)
	jr $ra

########################
# def print_bar(digit,length):
#i = 0
#print("\n",digit,"0s ",sep="",end="")
#while i < length:
#print("*", end="")
#i += 1
#print()
#
# $a0: digit - digit to print before the bar
# $a1: length - the length of the bar to print
########################
print_bar:
	move $s0, $a0 # save the digit we're working on

	# print "\n"
	li $v0, 4
	la $a0, newline
	syscall

	# print the digit (as integer)
	li $v0, 1
	move $a0, $s0 # this is the digit we want to print
	syscall

	# print "0s "
	li $v0, 4
	la $a0, label_0s
	syscall

	# print '*' length times
	li $t1, 0 # i = 0

pb_loop:
	slt   $t2, $t1, $a1 # check i < length
	beq   $t2, $zero, pb_done # branch out if i < length fails

	# print a *
	li $v0, 4
	la $a0, star_char
	syscall

	addi $t1, $t1, 1 # increment loop counter
	b pb_loop

pb_done:
	# trailing newline
	li $v0, 4
	la $a0, newline
	syscall

	jr $ra # return

Assignment

Finish translating the build_hist function into a MIPS procedure.

The translation should do the following (in order of priority):

  1. allow the function to behave just the same way as the Python program
  2. call the tens_digit procedure from inside the build_hist procedure
  3. inside build_hist, use the stack (with $sp) to save $ra and to make sure you restore any $s_ registers that you use to their values that they had before the procedure started. Note that you should also expect that tens_digit could change any of your $t_, $a_, or $v_ registers, so preserver them before making the call by putting them on the stack or putting them in $s_ registers.

Grading

This is an 8-point assignment. See the rubric from the syllabus, with the following exception:

The full 8 points will be for correct behavior with proper use of the stack and a call to tens_digit from within build_hist. You can get 7 points if it behaves correctly and you have utilized at least one of tens_digit and the stack. You can get 6 points for something that behaves correctly even if it uses neither of tens_digit nor the stack. You will get 5 points for significant progress towards the solution, even if it produces incorrect results.

What to turn in

Turn in the following items

  1. Your .asm file which contains your MIPS program
  2. A .txt file (you can use Notepad, TextEdit, or even Visual Studio Code) where you paste in a sample run of your program that shows how it worked when you ran it in MARS

Where to turn it in

Submit your files to the Assignment 3 hand-in form on Blackboard.