Reputation: 23
I am trying to extract integers from an array using MIPS Assembly language, then sum them up and print them. I'm using the MARS IDE to write this code, and I am very new to MIPS. It appears that the values are being correctly stored in the heap from the user input. However, I cannot figure out how to extract these values and add them to calculate the sum. Here's my code:
.data
numsArray: .word 100
prompt1: .asciiz "Enter an int n (# of integers): "
prompt2: .asciiz "Input "
prompt3: .asciiz " \nwith a space between each value, then press enter: "
newLine: .asciiz " \n"
inputString: .word 100
.text
main:
# Display enter n
li $v0, 4
la $a0, prompt1
syscall
# Get n from user input
li $v0, 5
syscall
move $t0, $v0 # Store n in $t0 instead of $v0 (we will need $v0 later)
# Calculate number of bytes needed for 0
move $a0, $t0 # move n to arg0
li $t4, 4 # 4 is size of an int (one word)
mul $a0, $a0, $t4 # multiply n by 4
mflo $t1 # move result from lo to $t1
# Allocate memory for 0 based on n * 4 ($t1)
li $v0, 9
move $a0, $t1
syscall
move $t2, $v0
# Display prompt for getting n values from user input
li $v0, 4
la $a0, prompt2
syscall # print prompt2
li $v0, 1
move $a0, $t0
syscall # print n
li $v0, 4
la $a0, prompt3
syscall # print prompt3
# Get the input string (containing n ints) from user
li $v0, 8 # syscall for read string
la $a0, inputString # load address of inputString
li $a1, 100 # set $a1 to max number of chars to read
syscall
la $t3, inputString # load address of word stored at inputString
# Loop to get n ints from user and put in memory
li $t4, 0 # start counter for getNIntsLoop
# Begin loop
getNIntsLoop:
# Currently:
# t0=n: Number of integers to retrieve
# t1=bytes_for_arr: Number of bytes needed for the array (4 * n)
# t2=addr_for_arr: Address where the integers will be stored
# t3=input_word_containing_nums: Address of the word stored at inputString
# t4=loop_counter: Counter for the number of integers retrieved so far
# t5=last_loaded_byte: Last byte loaded from the input string
# t6=uncalculated_sum: Variable to temporarily store the sum of integer
# Check if loop should end ($t4 == n)
beq $t4, $t0, endGetNIntsLoop # exit loop when all ints retrieved
# Load byte and check if it is a space or enter key
lb $t5, 0($t3) # load byte from input string at address stored in $t3
beq $t5, 31, skipFirstByte # check for unexpected control character (ASCII 31)
beq $t5, 32, saveLastInt # skip this parse and save int if char is a space (ASCII 32)
beq $t5, 10, saveLastInt # skip this parse and save int if char is an enter (ASCII 10)
# Not a space, continue parsing
subi $t5, $t5, 48 # convert ASCII to int
mul $t6, $t6, 10 # multiply current parsed int by 10
add $t6, $t6, $t5 # add current digit to current int
addi $t3, $t3, 1 # move to next byte in input string
j getNIntsLoop
skipFirstByte:
addi $t3, $t3, 1 # move to next byte (skip the control character)
j getNIntsLoop
saveLastInt:
# Save the parsed int to the array (assuming $t6 holds complete int)
sw $t6, 0($t2)
# TEST PRINTING VALS
li $v0, 1
move $a0, $t6
syscall
li $v0, 1
lw $a0, 0($t2)
syscall
li $v0, 4
la $a0, newLine
syscall
# TEST PRINTING VALS
addi $t2, $t2, 4 # move to next memory location in array
addi $t3, $t3, 1 # move to next byte in word
li $t6, 0 # reset $t5 to 0
addi $t4, $t4, 1 # increment count
j getNIntsLoop
endGetNIntsLoop:
la $t2, 0 # $t2 needs to be reset to base address of numsArray
# TEST PRINTING VALS
# PRINT THE ADDRESS TO ARRAY
li $v0, 34
la $a0, 0
syscall
li $v0, 4
la $a0, newLine
syscall
# TRY TO PRINT THE FIRST NUM IN ARR
li $v0, 1
la $t3, 0($t2)
srl $a0, $t3, 30
syscall
li $v0, 4
la $a0, newLine
syscall
# TRY TO PRINT ADDRESS FOR FIRST INT
li $v0, 34 # System call code for printing integer address
move $a0, $t3 # Load the address of the most significant byte
syscall
li $v0, 4
la $a0, newLine
syscall
# TRY TO PRINT THE 2nd INT IN ARR
lw $t3, 4($t2)
li $v0, 1
move $a0, $t3
syscall
# TEST PRINTING VALS
li $t5, 0 # $t5 will store the sum
getSumLoop:
beq $t4, $zero, endSumLoop # exit loop after all ints added to sum
lw $t6, 0($t2) # load int from memory
add $t5, $t5, $t6 # add int to sum stored in $t5
subi $t2, $t2, 4 # move to next int in numsArray
addi $t4, $t4, -1 # decrement loop counter (reusing old loop counter!)
j getSumLoop # call loop again
endSumLoop:
# Print sum stored at $t5
li $v0, 1 # syscall 1 == print integer
move $a0, $t5 # move sum stored in $t5 to $a0
syscall # print sum
# Exit program
li $v0, 10
syscall
I've added some test print statements. Thanks for any help.
Upvotes: 0
Views: 41
Reputation: 26646
.word 100
reserves one single word of storage initialized to 100, not what you want for an array.
.word 0:100
reserves 100 words of storage initialized to 0. Of course, you can use a different value for initializer there..
.align 2
.space 400
also reserves 100 words (400 bytes), properly aligned, and initialized to default (0). The alignment directive is useful because .space
works in bytes and doesn't offer any alignment (whereas .word
automatically provides word alignment).
Upvotes: 0