Search code examples
mips

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

  •     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.