Loop through MIPS Assembly
I am working on a program that iterates over an array of 10 numbers. The first 9 elements have values greater than 0, the 10th value has a value of 0. The loop must be aborted when 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 register value is 0. However, I don't know enough about manipulating values in memory.
This is my first time using MIPS and you will see a mess. If you can't fix this 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 lost the most:
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 contain the sum of all added values.
else:
add $a0, $v0, $zero #copy result as input to syscall
addi $v0,$zero,1 #service 1 for syscall is print integer
syscall
Executed with an infinite loop.
infinite: j infinite
source to share
To load a value from memory, you need to call one of the load instructions ( lw
, lh
or lb
for word, half-word, and byte). eg:
lw $a1, 0($a2) # load a word from the address in $a2 + offset 0 to $a1
to write a value to memory, you use one of the storage 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 with 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 commands 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 one moment:
You wrote addi $a1, $zero, 1 # i = i + 1
, but it is wrong. What you have done is save the result $zero + 1
that is 1
in $a1
. To increase $a1
, you need to write addi $a1, $a1, 1
which "saves the result $a1 + 1
to $a1
.
source to share