The following program
1. Prints out the array
2. Given a lower and upper bound input by user, determines the min and min index within that range
It runs the print array function.
However, I tried tracing the registers in QTSPIM, it does not correctly assign the lower bound and upper bound to $a0 and $a1 respectively. In fact, $v0 does not seem to even scan anything. To move the scanned input from $v0 to $t0, tried using "move $t0, $v0" instead. The problem still occurs.
# Ask the user for two indices
li $v0, 5 # System call code for read_int
syscall
add $t0, $v0, $zero # store input in $t0
sll $t0, $t0, 2 # relative address position (lower bound)
add $a0, $t9, $t0 # array pointer (lower bound)
li $v0, 5 # System call code for read_int
syscall
add $t0, $v0, $zero # store input in $t0
sll $t0, $t0, 2 # relative address position (upper bound)
add $a1, $t9, $t0 # array pointer (upper bound)
The full code is below. Can anyone enlighten me if there's anything wrong?
# arrayFunction.asm
.data
array: .word 8, 2, 1, 6, 9, 7, 3, 5, 0, 4
newl: .asciiz "\n"
.text
main:
# Print the original content of array
# setup the parameter(s)
la $a0, array # base address of array
add $t9, $a0, $zero # store base address
la $a1, 10 # number of elements in array
# call the printArray function
jal printArray # call function
# Ask the user for two indices
li $v0, 5 # System call code for read_int
syscall
add $t0, $v0, $zero # store input in $t0
sll $t0, $t0, 2 # relative address position (lower bound)
add $a0, $t9, $t0 # array pointer (lower bound)
li $v0, 5 # System call code for read_int
syscall
add $t0, $v0, $zero # store input in $t0
sll $t0, $t0, 2 # relative address position (upper bound)
add $a1, $t9, $t0 # array pointer (upper bound)
# Call the findMin function
# setup the parameter(s)
# call the function
jal findMin # call function
# Print the min item
# place the min item in $t3 for printing
addi $t3, $t1, 0
# Print an integer followed by a newline
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # print $t3
syscall # make system call
li $v0, 4 # system call code for print_string
la $a0, newl
syscall # print newline
#Calculate and print the index of min item
la $a0, array
add $t3, $v0, $a0
srl $t3, $t3, 2
# Place the min index in $t3 for printing
# Print the min index
# Print an integer followed by a newline
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # print $t3
syscall # make system call
li $v0, 4 # system call code for print_string
la $a0, newl #
syscall # print newline
# End of main, make a syscall to "exit"
li $v0, 10 # system call code for exit
syscall # terminate program
#######################################################################
### Function printArray ###
#Input: Array Address in $a0, Number of elements in $a1
#Output: None
#Purpose: Print array elements
#Registers used: $t0, $t1, $t2, $t3
#Assumption: Array element is word size (4-byte)
printArray:
addi $t1, $a0, 0 #$t1 is the pointer to the item
sll $t2, $a1, 2 #$t2 is the offset beyond the last item
add $t2, $a0, $t2 #$t2 is pointing beyond the last item
l1:
beq $t1, $t2, e1
lw $t3, 0($t1) #$t3 is the current item
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # integer to print
syscall # print it
addi $t1, $t1, 4
j l1 # Another iteration
e1:
li $v0, 4 # system call code for print_string
la $a0, newl #
syscall # print newline
jr $ra # return from this function
#######################################################################
### Student Function findMin ###
#Input: Lower Array Pointer in $a0, Higher Array Pointer in $a1
#Output: $v0 contains the address of min item
#Purpose: Find and return the minimum item
# between $a0 and $a1 (inclusive)
#Registers used: $t0 (counter), $t1 (max add), $t2 (min), $v0 (min pos), $t3 (current item)
#Assumption: Array element is word size (4-byte), $a0 <= $a1
findMin:
lw, $t2, 0($a0) # initialise min (value) to the lower bound
addi $t0, $a0, 0 # initialise $t0 (current pointer) to lower bound
addi $t1, $a1, 0 # initialise $t1 (add of end of array) to upper bound
Loop: slt $t4, $t1, $t0
bne $t4, $zero, End # branch to end if upper < lower
lw, $t3, 0($a0) # store the content of the lower array pointer
slt $t4, $t3, $t2 # if current ($t3) < min ($t2), store 1 in $t4
beq $t4, $zero, LoopEnd # if it is 0, go to LoopEnd
addi $t2, $t3, 0 # store content ($t3) as minimum ($t2)
addi $v0, $t0, 0 # store the address of min
LoopEnd: addi, $t0, 4 # increments current pointer lower bound
j Loop # Jump to loop
End:
jr $ra # return from this function
You read in the integers properly. The problems are elsewhere
findMin
function you use lw, $t3, 0($a0)
, but you should use it with $t0
instead of $a0
.$t1
as min value rather then $t2
which actually holds it.$v0
which holds the pointer for the min value, so you use some garbage data later on, not the intended one. add
, but it should be sub
.LoopEnd
the add is syntactically wrong. It should be addi $t0, $t0, 4
. But this maybe just some copy paste error.Here is the fixed code. Changed lined marked with ERROR.
# arrayFunction.asm
.data
array: .word 8, 2, 1, 6, 9, 7, 3, 5, 0, 4
newl: .asciiz "\n"
.text
main:
# Print the original content of array
# setup the parameter(s)
la $a0, array # base address of array
add $t9, $a0, $zero # store base address
la $a1, 10 # number of elements in array
# call the printArray function
jal printArray # call function
# Ask the user for two indices
li $v0, 5 # System call code for read_int
syscall
add $t0, $v0, $zero # store input in $t0
sll $t0, $t0, 2 # relative address position (lower bound)
add $a0, $t9, $t0 # array pointer (lower bound)
li $v0, 5 # System call code for read_int
syscall
add $t0, $v0, $zero # store input in $t0
sll $t0, $t0, 2 # relative address position (upper bound)
add $a1, $t9, $t0 # array pointer (upper bound)
# Call the findMin function
# setup the parameter(s)
# call the function
jal findMin # call function
# Print the min item
# place the min item in $t3 for printing
addi $t3, $t2, 0 # ERROR: min is in $t2 not $t1
addi $t4, $v0, 0 # ERROR: not saving the pointer to the min element
# Print an integer followed by a newline
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # print $t3
syscall # make system call
li $v0, 4 # system call code for print_string
la $a0, newl
syscall # print newline
#Calculate and print the index of min item
la $a0, array
sub $t3, $t4, $a0 # ERROR: sub should used not add
srl $t3, $t3, 2
# Place the min index in $t3 for printing
# Print the min index
# Print an integer followed by a newline
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # print $t3
syscall # make system call
li $v0, 4 # system call code for print_string
la $a0, newl #
syscall # print newline
# End of main, make a syscall to "exit"
li $v0, 10 # system call code for exit
syscall # terminate program
#######################################################################
### Function printArray ###
#Input: Array Address in $a0, Number of elements in $a1
#Output: None
#Purpose: Print array elements
#Registers used: $t0, $t1, $t2, $t3
#Assumption: Array element is word size (4-byte)
printArray:
addi $t1, $a0, 0 #$t1 is the pointer to the item
sll $t2, $a1, 2 #$t2 is the offset beyond the last item
add $t2, $a0, $t2 #$t2 is pointing beyond the last item
l1:
beq $t1, $t2, e1
lw $t3, 0($t1) #$t3 is the current item
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # integer to print
syscall # print it
addi $t1, $t1, 4
j l1 # Another iteration
e1:
li $v0, 4 # system call code for print_string
la $a0, newl #
syscall # print newline
jr $ra # return from this function
#######################################################################
### Student Function findMin ###
#Input: Lower Array Pointer in $a0, Higher Array Pointer in $a1
#Output: $v0 contains the address of min item
#Purpose: Find and return the minimum item
# between $a0 and $a1 (inclusive)
#Registers used: $t0 (counter), $t1 (max add), $t2 (min), $v0 (min pos), $t3 (current item)
#Assumption: Array element is word size (4-byte), $a0 <= $a1
findMin:
lw, $t2, 0($a0) # initialise min (value) to the lower bound
addi $t0, $a0, 0 # initialise $t0 (current pointer) to lower bound
addi $t1, $a1, 0 # initialise $t1 (add of end of array) to upper bound
Loop:
slt $t4, $t1, $t0
bne $t4, $zero, End # branch to end if upper < lower
lw, $t3, 0($t0) # store the content of the lower array pointer, ERROR: t0 should be used not a0
slt $t4, $t3, $t2 # if current ($t3) < min ($t2), store 1 in $t4
beq $t4, $zero, LoopEnd # if it is 0, go to LoopEnd
addi $t2, $t3, 0 # store content ($t3) as minimum ($t2)
addi $v0, $t0, 0 # store the address of min
LoopEnd:
addi $t0, $t0, 4 # increments current pointer lower bound
j Loop # Jump to loop
End:
jr $ra # return from this function