Lab 10
Lab 10
Question 1:
Write a MIPS program with the following requirements:
1. Declare an array that can store 8 data elements.
2. Request integers from the user and store them into the array.
3. Check whether each element in the array is divisible by 3.
4. If an element is divisible by 3, divide it by 3.
5. If an element is not divisible by 3, change it to the number divisible by 3 that is closest
to it, i.e, if the number is 32, the result will be 33.
6. Print the final array to the terminal.
Code
.data
array: .space 32
prompt: .asciiz "Enter an integer: "
result: .asciiz "\nFinal array: "
space: .asciiz " "
.text
main:
la $t0, array
li $t1, 8
input_loop:
beq $t1, $zero, process_array
li $v0, 4
la $a0, prompt
syscall
li $v0, 5
syscall
sw $v0, 0($t0)
process_array:
la $t0, array
li $t1, 8
process_loop:
beq $t1, $zero, print_array
lw $t2, 0($t0)
rem $t3, $t2, 3
beq $t3, $zero, divisible_by_3
divisible_by_3:
div $t2, $t2, 3
store:
sw $t2, 0($t0)
print_array:
li $v0, 4
la $a0, result
syscall
la $t0, array
li $t1, 8
print_loop:
beq $t1, $zero, exit
lw $t2, 0($t0)
li $v0, 1
move $a0, $t2
syscall
li $v0, 4
la $a0, space
syscall
addi $t0, $t0, 4
addi $t1, $t1, -1
j print_loop
exit:
li $v0, 10
syscall
RESULT
Question 2:
Using the same result as question 1, write a MIPS program to find the second largest
element in a 15-elements array. If the array has more than one second largest element,
find all their indexes. Print the value and all of its indexes. For example, if the array is 1,
2, 7, 7, 3, 7, 4, 5, 6, 7, 7, 8, 8, 8, 7 the output should be Second largest value is 7, found in
index 2, 3, 5, 9, 10, 14.
.data
array: .word 3, 3, 1, 6, 6, 2, 9, 9, 3, 3, 1, 6, 6, 2, 9
prompt: .asciiz "Second largest value is "
index_prompt: .asciiz ", found in index "
comma: .asciiz ", "
.text
main:
# Step 1: Find the largest element
la $t0, array # Load base address of array into $t0
lw $t1, 0($t0) # Load the first element
li $t2, 14 # Loop counter for the rest of the elements (15-1=14)
addi $t0, $t0, 4 # Point to the next element
move $t3, $t1 # $t3 stores the largest value found
largest_loop:
beqz $t2, find_second_largest # If counter reaches 0, go to find_second_largest
lw $t4, 0($t0) # Load next element
blt $t4, $t3, skip_largest_update # If $t4 < $t3, skip
move $t3, $t4 # Update largest value
skip_largest_update:
addi $t0, $t0, 4 # Move to the next array element
addi $t2, $t2, -1 # Decrease loop counter
j largest_loop
find_second_largest:
la $t0, array # Reset base address of array
li $t2, 15 # Reset loop counter
li $t5, -2147483648 # $t5 stores the second largest value, start with smallest
possible integer
li $t6, 0 # Counter for indices
second_largest_loop:
beqz $t2, print_result # If counter reaches 0, go to print_result
skip_second_update:
addi $t0, $t0, 4 # Move to the next array element
addi $t2, $t2, -1 # Decrease loop counter
j second_largest_loop
print_result:
li $v0, 4 # Print string syscall
la $a0, prompt
syscall
index_loop:
beqz $t2, exit # If counter reaches 0, exit
skip_index_print:
addi $t6, $t6, 1 # Increment index counter
addi $t0, $t0, 4 # Move to the next array element
addi $t2, $t2, -1 # Decrease loop counter
j index_loop
exit:
li $v0, 10 # Exit syscall
syscall
Question 3:
Write a MIPS program to check if the elements of a 10-elements array are unique
(appears only once in the array). If there are duplicated values in the array, print those
values. For example, if the array is 1, 2, 3, 3, 3, 1, 7 ,8, 9, 10 then the output should be
Unique values: 2, 7, 8, 9, 10. Duplicated value: 2, repeated 2 times; 5, repeated 3 times.
.data
# Array size
array_size: .word 10
.text
main:
# Load array size
lw $t0, array_size
init_found_count:
beq $t8, $zero, print_unique_msg
sw $t7, 0($t6)
addi $t6, $t6, 4
addi $t8, $t8, -1
j init_found_count
print_unique_msg:
# Print "Unique values:"
la $a0, unique_msg
li $v0, 4
syscall
loop1:
# Check if inner loop reached the end
beq $t1, $t0, check_duplicates # Exit if i == array_size
loop2:
# Check if outer loop reached the end (j >= array_size)
beq $t2, $t0, update_count # Exit if j >= array_size
increment_j:
addi $t2, $t2, 1 # Increment outer loop counter (j++)
j loop2
increment_count:
addi $t4, $t4, 1
j increment_j
update_count:
# Store the count of duplicates in found_count array
la $t6, found_count
add $t6, $t6, $t9
sw $t4, 0($t6)
check_duplicates:
# Print newline
la $a0, newline
li $v0, 4
syscall
print_loop:
beq $t1, $t0, exit # Exit if i == array_size
# Print value
li $v0, 1
move $a0, $t3
syscall
# Print newline
la $a0, newline
li $v0, 4
syscall
increment_i:
addi $t1, $t1, 1
j print_loop
exit:
# Exit program
li $v0, 10
syscall
Question 4:
Write a MIPS program that calculates and print either the volume or total surface area of
a rectangular box, cube, cylinder or rectangular pyramid. The user is able to choose
which metric, shape, and the related parameters to calculate. Note that the parameters can
be floating-point numbers.
.data
prompt_shape: .asciiz "\nChoose a shape: 1 for Rectangular Box, 2 for Cube, 3 for
Cylinder, 4 for Rectangular Pyramid: "
prompt_metric: .asciiz "\nChoose a metric: 1 for Volume, 2 for Total Surface Area: "
prompt_length: .asciiz "\nEnter the length: "
prompt_width: .asciiz "\nEnter the width: "
prompt_height: .asciiz "\nEnter the height: "
prompt_radius: .asciiz "\nEnter the radius: "
prompt_base_length: .asciiz "\nEnter the base length: "
prompt_base_width: .asciiz "\nEnter the base width: "
result_msg: .asciiz "\nThe result is: "
newline: .asciiz "\n"
.text
.globl main
print_float:
lw $v0, print_s
syscall
jr $ra
print_int:
lw $v0, print_i
syscall
jr $ra
read_int:
lw $v0, li_i
syscall
jr $ra
read_float:
lw $v0, li_s
syscall
jr $ra
main:
# Prompt for shape
la $a0, prompt_shape
jal print_string
jal read_int
move $t0, $v0 # $t0 stores shape choice
rect_box:
la $a0, prompt_length
jal print_string
jal read_float
mov.s $f0, $f0 # length in $f0
la $a0, prompt_width
jal print_string
jal read_float
mov.s $f1, $f0 # width in $f1
la $a0, prompt_height
jal print_string
jal read_float
mov.s $f2, $f0 # height in $f2
li $t2, 1
beq $t1, $t2, calc_rect_box_volume
li $t2, 2
beq $t1, $t2, calc_rect_box_surface_area
j end_program
calc_rect_box_volume:
mul.s $f3, $f0, $f1
mul.s $f4, $f3, $f2
j print_result
calc_rect_box_surface_area:
mul.s $f3, $f0, $f1
mul.s $f4, $f0, $f2
mul.s $f5, $f1, $f2
add.s $f6, $f3, $f4
add.s $f7, $f5, $f6
add.s $f4, $f7, $f7
j print_result
cube:
la $a0, prompt_length
jal print_string
jal read_float
mov.s $f0, $f0 # side length in $f0
li $t2, 1
beq $t1, $t2, calc_cube_volume
li $t2, 2
beq $t1, $t2, calc_cube_surface_area
j end_program
calc_cube_volume:
mul.s $f3, $f0, $f0
mul.s $f4, $f3, $f0
j print_result
calc_cube_surface_area:
mul.s $f3, $f0, $f0
li.s $f5, 6.0
mul.s $f4, $f3, $f5
j print_result
cylinder:
la $a0, prompt_radius
jal print_string
jal read_float
mov.s $f0, $f0 # radius in $f0
la $a0, prompt_height
jal print_string
jal read_float
mov.s $f1, $f0 # height in $f1
li $t2, 1
beq $t1, $t2, calc_cylinder_volume
li $t2, 2
beq $t1, $t2, calc_cylinder_surface_area
j end_program
calc_cylinder_volume:
li.s $f2, 3.14159
mul.s $f3, $f0, $f0
mul.s $f4, $f2, $f3
mul.s $f5, $f4, $f1
mov.s $f4, $f5
j print_result
calc_cylinder_surface_area:
li.s $f2, 3.14159
mul.s $f3, $f0, $f0
mul.s $f4, $f2, $f3
mul.s $f5, $f2, $f0
mul.s $f6, $f5, $f1
add.s $f7, $f4, $f6
add.s $f4, $f7, $f7
j print_result
pyramid:
la $a0, prompt_base_length
jal print_string
jal read_float
mov.s $f0, $f0 # base length in $f0
la $a0, prompt_base_width
jal print_string
jal read_float
mov.s $f1, $f0 # base width in $f1
la $a0, prompt_height
jal print_string
jal read_float
mov.s $f2, $f0 # height in $f2
li $t2, 1
beq $t1, $t2, calc_pyramid_volume
li $t2, 2
beq $t1, $t2, calc_pyramid_surface_area
j end_program
calc_pyramid_volume:
mul.s $f3, $f0, $f1
mul.s $f4, $f3, $f2
li.s $f5, 0.33333
mul.s $f6, $f4, $f5
mov.s $f4, $f6
j print_result
calc_pyramid_surface_area:
mul.s $f3, $f0, $f1
li.s $f5, 0.5
mul.s $f6, $f0, $f5
mul.s $f7, $f1, $f5
sqrt.s $f8, $f2
mul.s $f9, $f6, $f8
mul.s $f10, $f7, $f8
add.s $f11, $f9, $f10
add.s $f4, $f3, $f11
j print_result
print_result:
la $a0, result_msg
jal print_string
la $a0, newline
jal print_string
end_program:
lw $v0, exit_code
syscall
Result
Question 5:
Write a MIPS program to calculate the following integral:
.data
prompt_a: .asciiz "Enter a: "
prompt_b: .asciiz "Enter b: "
prompt_c: .asciiz "Enter c: "
prompt_d: .asciiz "Enter d: "
prompt_u: .asciiz "Enter u: "
prompt_v: .asciiz "Enter v: "
prompt_e: .asciiz "Enter e (last digit of student ID): "
result_text: .asciiz "The result of the integral is: "
.text
.globl main
main:
# Prompt user for a
li $v0, 4
la $a0, prompt_a
syscall
li $v0, 6
syscall
mov.s $f0, $f0 # a -> $f0
# term4 = (d / e^2) * u
div.s $f14, $f3, $f7 # f14 = d / e^2
mul.s $f14, $f14, $f4 # f14 = term4
# Compute F(v)
# term1 = (a / (5 * e^2)) * v^5
li.s $f9, 5.0
mul.s $f9, $f9, $f7 # f9 = 5 * e^2
div.s $f9, $f0, $f9 # f9 = a / (5 * e^2)
mul.s $f10, $f5, $f5
mul.s $f10, $f10, $f5
mul.s $f10, $f10, $f5
mul.s $f10, $f10, $f5 # f10 = v^5
mul.s $f9, $f9, $f10 # f9 = term1
# term2 = (b / (4 * e^2)) * v^4
li.s $f11, 4.0
mul.s $f11, $f11, $f7 # f11 = 4 * e^2
div.s $f11, $f1, $f11 # f11 = b / (4 * e^2)
mul.s $f12, $f5, $f5
mul.s $f12, $f12, $f5
mul.s $f12, $f12, $f5 # f12 = v^4
mul.s $f11, $f11, $f12 # f11 = term2
# term4 = (d / e^2) * v
div.s $f15, $f3, $f7 # f15 = d / e^2
mul.s $f15, $f15, $f5 # f15 = term4
# Print result
li $v0, 4
la $a0, result_text
syscall
li $v0, 2
mov.s $f12, $f16
syscall
# Exit program
li $v0, 10
Syscall
Question 6:
In this exercise, students are required to write a recursive program although the problem
can be solved by iterations. Write a MIPS program that calculates the sum of all 10
elements in a single precision floating point array with synthetic data. Bellow is pseudo
code of the recursive version:
.data
array: .float 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 11.0
n: .word 10
result: .asciiz "Result: "
.text
.globl main
mov.s $f1, $f0 # Save the result of the recursive call in $f1
lwc1 $f0, 0($s0) # Reload v[0] into $f0
add.s $f0, $f0, $f1 # $f0 = v[0] + result of sum(v + 1, k - 1)
base_case:
lwc1 $f0, 0($s0) # Load v[0] into $f0
end:
# Epilogue
lw $ra, 20($sp) # Restore return address
lw $s0, 16($sp) # Restore callee-saved register
lw $s1, 12($sp) # Restore callee-saved register
lw $s2, 8($sp) # Restore callee-saved register
addi $sp, $sp, 24 # Deallocate stack space
jr $ra # Return
# Main function
main:
la $a0, array # Load address of the array into $a0
lw $a1, n # Load the size of the array into $a1
la $a0, result
li $v0, 4
syscall
.data
array: .float 2.0, 24.1, 13.0, 4.5, 5.5, 6.7, 7.8, 8.9, 9.1, 10.0
result: .asciiz "Result: "
n: .word 10
.text
.globl main
mov.s $f1, $f0 # Save the result of the recursive call in $f1
lwc1 $f0, 0($s0) # Reload v[0] into $f0
c.le.s $f0, $f1 # Compare v[0] and the result of the recursive call
bc1f use_f1 # If v[0] > result of recursive call, branch to use_f1
mov.s $f0, $f1 # Otherwise, $f0 = max($f0, $f1)
use_f1:
j end # Jump to end
base_case:
lwc1 $f0, 0($s0) # Load v[0] into $f0
end:
# Epilogue
lw $ra, 12($sp) # Restore return address
lw $s0, 8($sp) # Restore callee-saved register
lw $s1, 4($sp) # Restore callee-saved register
addi $sp, $sp, 16 # Deallocate stack space
jr $ra # Return
# Main function
main:
la $a0, array # Load address of the array into $a0
lw $a1, n # Load the size of the array into $a1
# Divide to get the original integer part and the single decimal digit
li $t1, 10
div $t2, $t0, $t1 # $t2 = integer part
rem $t3, $t0, $t1 # $t3 = single decimal digit
la $a0, result
li $v0, 4
syscall