Loop through an array MIPS Assembly

49,109

To load a value from a memory, you need to call one of the load instructions, (lw, lh or lb for word, half-word and byte). for example:

lw $a1, 0($a2) # load a word from the address in $a2 + offset 0 to $a1

to write a value in memory, you use one of the store commands, for example:

sw $a1, 0($a2) # store the word in $a1 into the address in $a2 + offset

loading an address into a register is done using la, for example

la $a2, label_of_array # load the address of the label 'label_of_array' into $a2

Now, to manipulate the value in the array, you need to combine the three instructions from above:

la $a1, label_of_array   # load the address of the array into $a1
lb $a2, 0($a1)           # load a byte from the array into $a2
addi $a2, $a2, 1         # increment $a2 by 1
sb $a2, 0($a1)           # store the new value into memory
addi $a1, $a1, 1         # increment $a1 by one, to point to the next element in the array

And another point:

You wrote addi $a1, $zero, 1 # i = i + 1 but this is wrong. What you did is to store the result of $zero + 1 which is 1 into $a1. In order to increment $a1, you need to write addi $a1, $a1, 1 which is "store the result of $a1 + 1 into $a1.

Share:
49,109
user2079483
Author by

user2079483

Updated on February 17, 2020

Comments

  • user2079483
    user2079483 about 4 years

    I'm working on a program which loops through an array of 10 numbers. The first 9 elements have values higher than 0, the 10th has a value of 0. The loop should break when the 0 is encountered.

    i=0;
    while(A[i]!=0)
    {
        A[i]=A[i]+1;
        i++;
    }
    

    I know I can use 'beq' to break the loop if the value of the register is equal to 0. However I don't know enough about manipulating values in the memory.

    It's my first time using MIPS and you'll see it's a mess. If you can't fix it for me, can you give me some pointers?

    .data  #by default, the "data segment" starts at address 0x10010000
    .word 1
    .word 2
    .word 3
    .word 4
    .word 5
    .word 6
    .word 7
    .word 8
    .word 9
    .word 0
    
    .text #instructions start below
    
    # MIPS assembly code
    
    lui  $a0, 0x1001           # $a0 = 0x10010000
    addi $a1, $zero, 0         # i = 0
    jal increment              # call the procedure
    

    Here's where I'm most lost:

    increment:
    lui $a0, 0x1001           # $a0 = 0x10010000
    beq $a0, $zero, else      # if $a0 holds 0 goto 'else'
    addi $a0, $a0, 2          # +2
    addi $a1, $zero, 1        # i = i + 1
    
    jr $ra                   #jump to caller
    

    $v0 should hold the sum of all the incremented values.

    else: 
    add $a0, $v0, $zero #copy result as input to syscall
    addi $v0,$zero,1 #service 1 for syscall is print integer
    syscall
    

    Finishes with an infinite loop.

    infinite: j infinite
    
  • user2079483
    user2079483 about 11 years
    Thanks that's helpful. But how can I increase the offset with each loop of the array, or effectively use the index? Edit: Don't worry, I see it.
  • MByD
    MByD about 11 years
    Don't increase the offset, increase the register that holds the address of the array (as in the last line of the code sample I posted)
  • user2079483
    user2079483 about 11 years
    Yes, just noticed it. Thanks.