I'm a novice to MIPS

I'm trying to develop a program which takes an input from a ten word array, increments it by two, stores the result back into a register $v0. Which will hold the incremented value. The program should stop when it encounters a value of 0 from the array.

The first 9 elements of the array will start from 1 up to 9, with the tenth being a 0.

Another register will also be used to hold the sum of all incremented values.

I can also not make use of any pseudo code.

This is the code i have so far

.data
.word 1
.word 2
.word 3
.word 4
.word 5
.word 6
.word 7
.word 8
.word 9
.word 0

.text
lui $a0, 0x1001 #load address 0x1001000 of the array into register $a0
jal incrment #call the procedure
increment:
lw $a2, 0($a0) #load word from register $a0 into $a2
beq $a2, $zero, else #if word loaded is 0 goto else
addi $a2, $a2, 2 #add two
sw $a2, 0($a0) #store result from $a2 back into $a0
addi $a0, $a0, 1 #add 1 to $a0 to point to the next value in the array
addi $v0, $a2, $zero #add the result from $a2 into $v0
addi $v0, $zero, 1
syscall
jr $a0
j increment #jump back to the procedure
else:
add $v1, $a0, $zero #once the 0 is found, store the final sum from $a0 into $v1
addi $v1, $zero, 1
syscall

I feel like the logic is correct but the semantics of the code are lacking

The code may seem like a bit of a mess, another area I'm also unsure about is the index, i'm supposed to use another register to hold the 0 based index of the array?

If you can't fix it, then could you give me some pointers? Thanks

Recommended Answers

All 3 Replies

The first thing I'll recommend is indenting the code by four spaces, except for the labels; this should make it easier to read. However, I can't tell if you did that or not already, because you didn't paste the code in using the CODE button, and the forum software does not by default retain formatting. So, what you want to do when you post some code is, click on where it says 'Code' at the top of the editing window and paste the code sample into the code window that pops up (if you have a pop-up blocker, you may have to disable it).

The next thing I'll ask is, what emulator or simulator are you using? There are several around for MIPS processor, the most common being SPIM and MARS. While they are mostly the similar, they are some differences in the exact code each takes. If you can tell us which you are using, it would help us figure out what to suggest.

Next, I would suggest using a label for the array, rather than trying to use an absolute memory location. Pretty much any asembler will accept data labels, and most (including SPIM and MARS) let you have more than one piece of data on a line of code.

I would also put a call to system call 10 (exit) at the end of the main function.

Also, by default, the register $ra holds the return address for the function, so the instruction jr should almost always use $ra as its argument.

Finally, if you are allowed to by your professor and your assembler, I would suggest using some of the pseudo-instructions, most specifically move, la, and li. While you can do most of these things without them, they make things much, much easier.

    .data
array: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 0

    .text

main:       
    la $a0, array  #load the address of the array into register $a0
    jal increment    #call the procedure
    li $v0, 10 # exit the program
    syscall

increment:
    lw $a2, 0($a0) #load word from register $a0 into $a2
    beq $a2, $zero, else #if word loaded is 0 goto else
    addi $a2, $a2, 2 #add two
    sw $a2, 0($a0) #store result from $a2 back into $a0
    addi $a0, $a0, 1 #add 1 to $a0 to point to the next value in the array
    addi $v0, $a2, $zero #add the result from $a2 into $v0
    addi $v0, $zero, 1
    syscall
    j increment #jump back to the procedure

else:
    add $v1, $a0, $zero #once the 0 is found, store the final sum from $a0 into $v1
    addi $v1, $zero, 1
    syscall
    jr $ra

Hello, thanks for replying with so much depth. I'm using the MARS 4.4. Though, i can't make use of any psuedo code. I'm fairly new to assembly, alledgedly to test if this works all the non zero array elements should all be incremented by two and when the procedure is complete the return value should be 63? Not entirely sure how to evaluate if that's the case or not. Thanks

Though, i can't make use of any psuedo code.
By that, I assume you mean pseudo-instructions or macro instructions (pseudo-code being something completely different)? I was afraid of that when I saw you were loading an absolute address into $a0. It is an unreasonable requirement, as it forces you to do things the assembler should be doing, but I know that a lot of instructors seem to think it is a good idea for some reason.

<rant>
The problem with that is that it makes loading the address of an assembler label impossible, as you would need to be able to access information internal to the assembler in order to do it. This forces you to use absolute addresses, which is ludicrous. No sane programmer uses fixed addresses unless absolutely necessary, even in assembly language. Labels have been a part of assembly language from the start, and not being able to use them for a reasonable purpose is simply unacceptable. A professor who imposes such meaningless and arbitrary demands on their students should be dismissed from teaching.
</rant>

As for how to tell whether the final value is right, the easiest way is to use syscall 1 to print out the result:

    .data
array: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 0

    .text

main:       
    lui $a0, 0x1001000   #load the address of the array into register $a0
    jal increment        #call the procedure
    add $a0, $0, $v0     # shift the return value to the argument
    addi $v0, $0, 1      #print the number out
    syscall

    addi $v0, $0, 10     #exit the program
    syscall

increment:
    lw $a1, 0($a0)       #load word from register $a0 into $a2
    beq $a1, $zero, else #if word loaded is 0 goto else
    addi $a1, $a1, 2     #add two
    sw $a1, 0($a0)       #store result from $a2 back into $a0
    addi $a0, $a0, 1     #add 1 to $a0 to point to the next value in the array
    addi $v0, $v0, $a1   #add the result from $a1 into $v0
    addi $v0, $zero, 1
    syscall
    j increment          #jump back to the procedure

else:
    jr $ra
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.