adamruehle
adamruehle

Reputation: 23

How do I extract ints from an array using MIPS Assembly?

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

Answers (1)

Erik Eidt
Erik Eidt

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

Related Questions