'partition function in c and MIPS
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!
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Raymond Chen |