Question
QTSPIM # Description: # # Problem Statement: Allocate a dynamic array of custom length to store double precision float values. Read the double precision values
QTSPIM # Description:
#
# Problem Statement: Allocate a dynamic array of custom length to store double precision float values. Read the double precision values one by one from
# the user and store them into the previously declared array. Atlast print the "sum" and "average" of array elements.
#
# In this program there are three subporograms. All the arguments will be passed through stack.
# 1. allocate_array:
# Called from "main".
# IN: None
# OUT: Base Address of the array, Length of the array.
# Function: Takes a valid array length from the user and allocate an array to store double precision float values of the
# user specified length.
# 2. read_double_array:
# Called from "main".
# IN: Base Address of the array, Length of the array.
# OUT: Sum of the array elements, average of array elements.
# Function: This subprogram reads double precision float values from the user one by one and store them in the previously
# decalred array sequentially. It stops taking input from the user when the array is filled. Then it calls another
# subprogram named "get_sum_avg" to get the sum and average of all the elements of the array. It passes the base address
# and the length of the array to the "get_sum_avg" subprogram and gets back "sum" and "average" of all the elements.
# Then it returns the sum and average to the main.
# 3. get_sum_avg:
# Called from "read_double_array" subprogram.
# IN: Base Address of the array, Length of the array.
# OUT: Sum of the array elements, average of array elements.
# Function: This subprogram calculate the sum of all the elements of the array by traversing through the array. Then calculate the
# average by dividing the sum by number of elements. Then it returns the sum and average to the "read_double_array" subprogram.
#
# Main:
# => Call "allocate_array" subprogram to allocate the dynamic array.
# => Store the base address and length of the array into static variables.
# => Call "read_double_array" subprogram. It reads the values one by one from the user, put them in the array. Once It has finish reading
# values call "get_sum_avg" subprogram. To calculate sum and average of the array elements. Return sum and average to "main".
# => Calculate sum and average of array elements and return those to "read_double_array" subprogram.
# => Fetch "sum" and "average" from stack after returning from read_double_array" subprogram and put them into double type static variables.
# => Print sum and average to the console.
#
###########################################################
###########################################################
# Register Usage
# $t0 Holds array base address (temporarily)
# $t1 Holds array length (temporarily)
# $t2
# $t3
# $t4
# $t5
# $t6
# $t7
# $t8
# $t9 temporary register
# $f4|$f5 Holds array sum (double-precision floating-point)
# $f6|$f7 Holds array average (double precision floating-point)
###########################################################
.data
sum_p: .asciiz "Array sum is: "
average_p: .asciiz "Array average is: "
sum: .double 0.0
average: .double 0.0
nextline_p: .asciiz " " #
# declare words to hold dynamic array base and array length
array_pointer_p: .word 0 # holds address dynamic array pointer (address)
array_size_p: .word 0 # hold length of dynamic array (value)
###########################################################
.text
main:
# Allocating space in Stack for IN/OUT argument.
jal allocate_array # Calling "allocate_array" subprogram.
# Load back the returned base address of dynamic array
# Load back the returned length of dynamic array
# Deallocate previously allocated space from stack.
la $t9, array_pointer_p # Store the base address of the array in static variable.
la $t9, array_size_p # Store the length of the array in static variable.
addi $sp, $sp, -24 # Allocate space in stack for IN/OUT arguments. 2-IN(Word)/2-OUT(Double Precision Float)
# Store the base address of array in stack as argument IN.
# Store the length of array in stack as argument IN.
jal read_double_array # Call "read_double_array" subporogram.
# Load back returned sum of array elements from stack
# Load back returned average of array elements from stack
# Deallocate previously allocated space from stack.
la $t9, sum # Store the sum in static variable.
la $t9, average # Store the average in static variable.
li $v0, 4
la $a0, sum_p
syscall
# Print the sum. Sum is of type double so syscode is '3' and argument IN register is $f12.
li $v0, 4
la $a0, nextline_p
syscall
li $v0, 4
la $a0, average_p
syscall
# Print the average. Average is of type double so syscode is '3' and argument IN register is $f12.
mainEnd:
li $v0, 10
syscall # Halt
###########################################################
# allocate_array subprogram
#
# Subprogram description:
# This subprogram receives no argument IN. This subprogram prompts user for array length and validate the array length.
# Then, allocate a dynamic array to hold double precision float values of the specified length. Remember size of a double precision
# float value is 8 bytes. So, to convert the array length/ number of elements into total number of bytes you have to multiply the
# length by 8. After allocating the array, this subprogram should return the base address and the length to the "main" using stack.
#
#
###########################################################
# Arguments IN and OUT of subprogram
# $sp+0 Holds array base address (OUT)
# $sp+4 Holds array length (OUT)
###########################################################
# Register Usage
# $t0
# $t1 Holds array length(Optional)
###########################################################
.data
allocate_array_prompt_p: .asciiz "Enter the array length: "
allocate_array_error_p: .asciiz "Please enter a value greater than 0 "
###########################################################
.text
allocate_array:
li $v0, 4
la $a0, allocate_array_prompt_p # Prompt for array length.
syscall
li $v0, 5 # Read the array length.
syscall
blez $v0, allocate_array_error # Validate array length.
move $t1, $v0
move $a0, $v0 # Allocate dynamic array to store double precision float values.
# Store base address of the dynamic array in stack to return.
# Store length of the dynamic array in stack to return.
allocate_array_end:
jr $ra # jump back to the main
allocate_array_error:
li $v0, 4
la $a0, allocate_array_error_p # Print conditional error message.
syscall
b allocate_array
###########################################################
# read_double_array subprogram
#
# Subprogram description:
# Reads double-precision floating-point numbers into an array. Print a prompt before reading each double number. Once the array is filled it will
# stop reading numbers from the user and call another subprogram named "get_sum_avg" to claculate the sum and average of all the array elements.
# It returns calculated sum and average to the "main".
#
###########################################################
# Arguments IN and OUT of subprogram
# $sp+0 Holds array base address (IN)
# $sp+4 Holds array length (IN)
# $sp+8 Holds Sum of the array elements (OUT)
# $sp+16 Holds average of the array elements (OUT)
# Size of stack increase by 4 bytes to call "get_sum_avg" subprogram from inside of this subprogram.
# $sp+0 Backs up the content of $ra register.
# Size of stack increase by 24 bytes to accomodate IN&OUT arguments of "get_sum_avg" subprogram.
# $sp+0 Holds array base address (IN)
# $sp+4 Holds array length (IN)
# $sp+8 Holds Sum of the array elements (OUT)
# $sp+16 Holds average of the array elements (OUT)
###########################################################
# Register Usage
# $t0 Holds array base address
# $t1 Holds array length/loop countdown
# $f0|$f1 Holds array entry
# $f4|$f5 Holds sum
# $f6|$f7 Holds average
###########################################################
.data
read_double_array_prompt_p: .asciiz "Enter a real number: "
###########################################################
.text
read_double_array:
# save arguments so we do not lose them
lw $t0, 0($sp) # load array base address
lw $t1, 4($sp) # load array length
read_double_array_loop:
blez $t1, read_double_array_sum_avg_calc # while($t1 > 0)
li $v0, 4 # prompt and read a number
la $a0, read_double_array_prompt_p
syscall
# read double-precision floating-point number
# read double-precision floating-point number
# increment array pointer (address) to next two words (each double-precision floating-point number is 8 bytes)
addi $t1, $t1, -1 # decrement array counter (index)
b read_double_array_loop # branch unconditionally back to beginning of the loop
read_double_array_sum_avg_calc:
lw $t0, 0($sp) # load array base address from stack
lw $t1, 4($sp) # load array length from stack
# Allocate space in stack to backup $ra.
# Backing up the current value of $ra in stack.
# Size of stack increase by 24 bytes to accomodate IN&OUT arguments of "get_sum_avg" subprogram.
# store array base address in stack to pass it as an argument IN.
# load array length in stack to pass it as an argument IN.
jal get_sum_avg # Call "get_sum_avg" subporogram.
# Load back returned sum of elements from stack.
# Load back returned average of elements from stack.
# Deallocate previously allocated space for "get_sum_avg" subporogram from stack.
# Load backed up $ra value from stack, so that this subprogram can returned to main.
# Deallocate the space from stack which was allocated to back-up content of $ra.
read_double_array_end:
# Return sum
# Return average
jr $ra # jump back to the main
###########################################################
# get_sum_avg subprogram
#
# Subprogram description:
# Calculate sum and average of an array of doubles. First calculate the sum of all the elemnts of the array by traversing through the array and then calculate
# the average by dividing the sum by length. It returns calculated sum and average to "read_double_array" subprogram.
#
# Remember, to calculate average we need to divide sum (:: double) / (:: integer)
# But there is no type promotion (or widening primitive conversion)in MIPS, which mean as a programmer we have to
# implicitly convert count to double before being able to sum by count.
#
###########################################################
# Arguments IN and OUT of subprogram
# $sp+0 Holds array base address (IN)
# $sp+4 Holds array length (IN)
# $sp+8 Holds array sum {double precision floating-point number} (OUT)
# $sp+16 Holds array average {double precision floating-point number} (OUT)
###########################################################
# Register Usage
# $t0 Holds array index address
# $t1 Holds array length/loop countdown
# $t2 Holds loop countdown
# $f4|$f5 Holds array Sum
# $f6|$f7 Holds array Average
# $f8|$f9 Holds array value/Count
###########################################################
.data
get_sum_avg_invalid_count_p: .asciiz "Invalid count, cannot calculate average "
###########################################################
.text
get_sum_avg:
# save arguments so we do not lose them
# load array base address
# load array length
li.d $f4, 0.0 # initialize sum to zero
li.d $f6, 0.0 # initialize average to zero
move $t2, $t1 # copy length into $t2 so we do not lose it
bgtz $t1, get_sum_avg_valid_count # if($t1 <= 0) then print error message and return 0.0 for both sum and average
li $v0, 4 # print invalid count error message
la $a0, get_sum_avg_invalid_count_p
syscall
b get_sum_avg_end # branch unconditionally to the end of subprogram
get_sum_avg_valid_count:
get_sum_avg_loop:
blez $t2, get_sum_avg_loop_end # while($t2 > 0)
# load array value
# add the number with the sum and put the result back to the sum
# increment array pointer (address) to next two words (each double-precision floating-point number is 8 bytes)
addi $t2, $t2, -1 # decrement array counter (index)
b get_sum_avg_loop # branch unconditionally back to beginning of the loop
get_sum_avg_loop_end:
# move to co-processor 1 from $t1
# convert count to double
# $f6|$f7 <-- $f4|$f5 / $f8|$f9
get_sum_avg_end:
# return sum
# return average
jr $ra # jump back to the "read_double_array" subporogram.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started