Frage

So I have a task in MIPS that I am currently stuck on. My task is too:

1) Write a loop that starts at first element of the array 2) Then adds 1 to each element in turn and storing the result back into the array 3) If zero is encountered, quit the program

Here's what I have already:

.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
lui $s0, 0x1001     # $s0 holds base address of the array
addi $s1, $zero, 0  # $s1 holds the index of the array
jal increment       # call loop procedure

increment:
beq $s0, $zero, Exit    # if $s0 value is zero, branch and go to else
addi $s0, $s0, 1    # adds 1 to each element
addi $s1, $s1, 1    # i = i + 1

j increment     # jump back to loop

Exit:
infinite: j infinite 

The problem I have when I run it, is that it keeps on running. And I know that the 10th word (.word0) contains the value 0.

Where a bouts in my code am I going wrong?

Many thanks


@Robert B, This is what I have now:

main: #instructions start below
la $s0, myData      # $s0 holds base address of the array
addi $s1, $zero, 0  # $s1 holds the index of the array

loop:
beq $s0, $zero, else    # if $s0 value is zero, branch and go to else
addi $s0, $s0, 2    # adds 2 to each element
addi $s1, $s1, 1    # i = i + 1

j loop      # call loop procedure

else:
addi $v0, $zero, 10     # terminate execution
syscall 
War es hilfreich?

Lösung

I see a few potential issues.

.text #instructions start below

While it's true that the executable instructions start after .text, it would be a good idea to define a label called main: there. The emulators see that and know unambiguously where to start (at least, I think that's how they're configured by default.)

lui $s0, 0x1001     # $s0 holds base address of the array
addi $s1, $zero, 0  # $s1 holds the index of the array

You're making a big, implementation-dependent assumption here. It's a better idea to add a label that points to your first data item:

.data  # Maybe the "data segment" starts at address 0x10010000, maybe it doesn't
myData:
.word 1
.word 2
...

Now, you can load the address of the label into $s1. The code below is actually a pseudo-opcode that will be expanded into a lui and an addi by the compiler.

la $s0, myData

The compiler will probably come up with the exact code that you started out with, pointing to address 0x10010000... but you're better off letting the compiler make that decision.

Finally, there's the question of why you do a jal here:

jal increment       # call loop procedure
increment:

Unless you've omitted some code for clarity, you're jump-and-linking to the next address. That doesn't make a lot of sense. You only need to use jal when you're calling a subroutine. The subroutine will return to the line after jal by doing a j $ra.

Oh yeah, and there's the infinite loop that your prof wants you to use. That's just strange. What's wrong with a syscall 10?

li  $v0, 10 # terminate execution
syscall

Andere Tipps

Having infinite jump to itself is at least part of the problem.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top