I was trying to write some MIPS code that simulates a C function, but it seems like I've come across an obstacle that I cant get over it.
int partition(int f, int l) {
int pivot = v[l];
int i = f;
for (int j = f; j < l; j++)
if(v[j] < pivot)
swap(i++,j);
swap(i, l);
return (i);
}
that was the function in C and this is what I have written so far in MIPS assembly language:
partition:
addi $sp, $sp, -8 #creates space for 2 words
sw $ra, 0($sp) #stores ra in stack
sw $a1, 4($sp) #stores a1 in stack
la $s0, v #stores ad. of v[0] in s0
sll $t0, $a1, 2 #stores 4 * l in t0
add $t0, $t0, $s0 #stores ad. of v[l] in t0
lw $s1, 0($t0) #loads v[l] in s1, s1 is pivot
add $t1, $a0, $zero #loads f in t1, t1 is 'i'
add $t2, $a0, $zero #loads f in t2, t2 is 'j'
for1: slt $t3, $t2, $a1 #checks if j < l
beq $t3, $zero, exit
sll $t4, $t2, 2 #t4 stores 4 * j
add $t4, $t4, $s0 #t4 stores ad. of v[j]
lw $t5, 0($t4) #t5 stores value of v[j]
slt $t3, $t5, $s1 #checks if v[j] < pivot
beq $t3, $zero, bfor #jumps to next repetition of the loop
add $a0, $t1, $zero #a0 is i
add $a1, $t2, $zero #a1 is j
jal swap #call swap
addi $t1, $t1, 1 # i++
j bfor #continue loop
bfor: lw $a1, 4($sp) #restores a1
addi $t2, $t2, 1 # j++
j for1 #continue loop
exit: add $a0, $t1, $zero #a0 is i
lw $a1, 4($sp) #restores initial a1
jal swap #call swap
add $v0, $t1, $zero #return i
lw $ra, 0($sp) #restore initial ra
addi $sp, $sp, 8
jr $ra
It is stated that f and l are stored in $a0 and $a1 respectively, the swap function is already created and the vector v is labeled in the memory. I cant understand where my mistake is and any help is welcome. Thanks in advance!
partition:
addi $sp, $sp, -16 #adjust stack for 4 items
sw $ra, 0($sp) #store ra in stack
sw $s0, 4($sp) #store s0
sw $a0, 8($sp) #store a0
sw $a1, 12($sp) #store a1
la $s0, v #load address of v0 in s0
sll $t0, $a1, 2 #t0 stores 4 * l
add $t0, $t0, $s0 #t0 stores ad. of v[l]
lw $t1, 0($t0) #t1 contains v[l] (t1 pivot)
add $t2, $a0, $zero #t2 is f (t2 i)
add $t3, $a0, $zero #t3 is f (t3 j)
for1: slt $t4, $t3, $a1 #sets 1 to t4 if j < l
beq $t4, $zero, exit
sll $t5, $t3, 2 #t5 is 4 * j
add $t5, $t5, $s0 #t5 stores ad. of v[j]
lw $t6, 0($t5) #t6 has the value of v[j]
slt $t4, $t6, $t1 #sets 1 to t4 if v[j] < pivot
beq $t4, $zero, bfor
add $a0, $t2, $zero #a0 is i
add $a1, $t3, $zero #a1 is j
addi $sp, $sp, -12 #adjust stack for 3 items
sw $t1, 0($sp)
sw $t2, 4($sp)
sw $t3, 8($sp) #store pivot, i, j in stack
jal swap #call swap
lw $t1, 0($sp)
lw $t2, 4($sp)
lw $t3, 8($sp) #restores pivot, i, j before the call
addi $sp, $sp, 12 #return items to stack
lw $a1, 12($sp) #restore initial a1
addi $t2, $t2, 1 #i++
j bfor
bfor: addi $t3, $t3, 1 #j++
j for1 #continue loop
exit: add $a0, $t2, $zero #a0 is i
addi $sp, $sp, -4 #adjust stack for 1 item
sw $t2, 0($sp) #store i
jal swap #calls swap
lw $v0, 0($sp) #returns i
addi $sp, $sp, 4 #returns item to stack
lw $ra, 0($sp) #restore initial ra in stack
lw $s0, 4($sp) #restore initial s0
lw $a0, 8($sp) #restore initial a0
lw $a1, 12($sp) #restore initial a1
addi $sp, $sp, 16 #return items to stack
jr $ra
I found the solution. Thank you to those who replied.
The important change is that the values in registers $t1, $t2, and $t3 are preserved across the call to swap, because swap modifies them.
rol $t7, $t6, $t8
This is like:
sll $t0, $t3, 8 # get rid of bits 31-23
srl $t1, $t3, 24 #move 31-32 to 7-0
or $t7, $t0, $t1 # do an or statement
right?
What about this one:
ld $t2, 0($t8)
Recently, I am learning MIPS. Professor give us an example of his code, asking us to find out the value. My problem is that after I type in his code, the run time exception comes out at " lw $t1, 0($s0) ".
line 8: Runtime exception at 0x0040001c: address out of range 0x00000000
Can someone helps me?
addi $t7, $zero,0x10010000
lw $t0, 20($t7)
srl $t0, $t0, 16
andi $t0, $t0, 0x00000FF
andi $s0, $t7, 16
lw $t1, 0($s0)
andi $t1, $t1, 0x0000FF00
srl $t1, $t1, 8
addi $s0, $s0, -8
lw $t2, 0($s0)
sll $t2, $t2, 24
srl $t2, $t2, 24
addi $s0, $zero, 1
sll $s0, $s0, 4
lw $t3, 0($t7)
srlv $t3, $t3, $s0
andi $t3, $t3, 255
addi $s0, $zero, 1
sll $s0, $s0, 2
add $s0, $s0, $t7
lw $t4, 0($s0)
andi $t4, $t4, 0x00FF0000
srl $t4, $t4, 16
May I ask if I have gotten it right for the following inequality equivalent in MIPS? Or is there any better way to implement with the basic commands of slt and bne and bqe?
less than <
slt $t0, $s1, $s2
beq $t0, $zero, L
....
L:
less than equals <=
addi $s2, $s2, 1
slt $t0, $s1, $s2
beq $t0, $zero, L
....
L:
greater than >
slt $t0, $s1, $s2
bne $t0, $zero, L
....
L:
greater than equals >=
addi $s2, $s2, 1
slt $t0, $s1, $s2
bne $s0, $zero, L
In this MIPS program
When this code fragment is run, how many instructions will be executed in total?
i1: ori $t0, $0, 1000
i2: ori $t1, $0, 2000
i3: addi $t2, $t0, 100
i4: lw $t3, 0($t1)
i5: lw $t4, 0($t0)
i6: add $t3, $t3, $t4
i7: sra $t3, $t3, 1
i8: sw $t3, 0($t0)
i9: sw $t3, 0($t1)
i10: addi $t0, $t0, 4
i11: addi $t1, $t1, 4
i12: slt $t3, $t0, $t2
i13: bne $0, $t3, i4
On every cycle, it adds 4 to $t0, which is initialized to 1000. At the end of the cycle, it checks if $t0 is greater than $t2, which is initialized to 1100. If it is, then the cycle breaks. So, it's the original 13 instructions, plus 10 for every cycle until it breaks. And it cycles an additional 25 times. And I may have added wrong, but if not, it's 263 instructions.