I wrote a program which takes input of a few numbers and loops through every one. Then it should swap the maximum if the current number is bigger than my last max one. If it's at the last number (at the end of my string), it should exit.
I'm trying to debug and I understand, that I didn't really understand how pointers work and when I have to use brackets around my registers.
The code is as follows:
.data
first: .word 5, 6, -128, -5, 260, 34, 3, 20, -1
last: .word 44
max: .space 4
.text
lw $t0, first
lw $t1, last
lw $t5, max
sw $t5, $t0
loop:
beq $t0, $t1, ex
addi $t0, $t0, 4
bgt $t0, $t5, swapmax
j loop
swapmax:
lw $t0, ($t5)
ex:
lw $t5, max
li $v0, 10
syscall
Where do I need brackets and why?
The program does compile, but I get an error:
attempt to execute non-instruction at 0x800000180
What does this error mean?
Pointers are something that point at a memory location. We use pointers to put values in memory locations. For example in C:
int max;
int *ptr = &max;
*ptr = 22; // max = 22
In above example, ptr is pointing at a memory location (max), and we change the value of max through ptr
by dereferencing it.
To understand this, you need to understand the instruction syntax and what operands each instruction takes. Obviously we cannot go through all the instructions in one answer so I will just show you a few so that you get an idea:
lw register, memory_location
sw register, memory_location
la register, memory_location
lw
loads a word from memory into register. Examples:lw $t0, first
lw $t0, ($t5) # this is like, int t0 = *t5
sw
stores a value from register into memory location. Example:sw $t0, max # max = t1
sw $t0, ($t5) # *t5 = t0
la
will load address of a memory location into a register.la $t5, max # int *t5 = &max
Let's see the mistakes in your code now. Here:
lw $t5, max
Above will load value of max
into $t5
. It seems like you created max
to store max value. Loading it here seems pointless because it doesn't even contain anything. You want to load it's address using la
:
la $t5, max #load address of max variable into $t5
Moving on we see this instruction:
sw $t5, $t0
This will not assemble. It will result in an error. sw
has first operand(source) as a register, and the second operand is a "memory location", not a register.
sw register, memory_location
So, if you want to store something, you would do:
sw $t5, ($t0) #store value inside $t5 at the 'address' inside $t0.
# Assume:
# $t5 = 23
# $t0 = 0x5555
# After executing this instruction, memory location 0x5555 would have value 23 in it
This was just explanation. In your code above, you assigned $t0 = first
. It isn't even pointing to a memory location! However, $t5 will have a memory location if you do la $t5, max
.
So, I assume you wanted to do:
sw $t0, ($t5)
# After executing this, 'max' == $t0 because $t5 is pointing at max.
Moving on, we see:
bgt $t0, $t5, swapmax
As you must already have guessed, this is incorrect. Reason: You are comparing an "address" with a value. "Address" is in $t5, "Value" is in $t0. If you want to get the value inside $t5, you will have to load it first. Maybe using another register:
lw $t3, ($t5)
#OR
lw $t3, max # same thing, $t5 is pointing at 'max'
These are the obvious mistakes. There maybe logical errors, but this is your code and your program so I will leave it to you to modify your logic as required