title: MIPS function call with more than four arguments
body: <p>I understand that whenever I have a function that has more than four arguments in MIPS I should utilize the stack. However in my code below after saving the fifth argument at <code>sw $t0, 4($sp)</code> and do a <code>jal sad</code>, then right at the beginning of the <code>sad</code> function I adjust the stack pointer again to save the <code>$sx</code> registers that is used by the caller. Am I doing something wrong here?</p>
  
  <pre><code>vbsme:  subu    $sp, $sp, 8     # create space on the stack pointer
      sw  $ra, 0($sp)     # save return address   
  
      li  $v0, 0          # reset $v0 
      li  $v1, 0          # reset $v1
      li  $s0, 1          # i(row) = 1 
      li  $s1, 1          # j(col) = 1
      lw  $s2, 0($a0)     # row size
      lw  $s3, 4($a0)     # col size
      mul     $s4, $s2, $s3       # row * col
      li  $s5, 0          # element = 0
  loop:   bgeq    $s5, $s4, exit      # if element &gt;= row * col then exit
  
      subi    $a3, $s0, 1     # 4th parameter: i-1
      subi    $t0, $s1, 1     
      sw  $t0, 4($sp)     # 5th parameter: j-1
  
      jal     sad         # calculate the sum of absolute difference using the frame starting from row a3 and col 4($sp)
  
      add $s6, $s0, $s1
      andi $s7, $s6, 1
  if: bneq $s7, $zero, else
  inif:   bge $s1, $s2, inelse
      addi $s1, $s1, 1
      j inif1
  inelse: addi $s0, $s0, 2
  inif1:  subi $s7, $s0, 1  
      beq $s7, $zero, loop_back
      subi $s0, $s0, 1
      j loop_back
  else:   bge $s0, $s2, inelse1
      addi $s0, $s0, 1
      j inif2
  inelse1:addi $s1, $s1, 2
  inif2:  subi $s7, $s1, 1  
      beq $s7, $zero, loop_back
      subi $s1, $s1, 1
      j loop_back
  loop_back: addi $s5, $s5, 1
         j loop
  exit:   lw  $ra, 0($sp)     # restore return address
      addi    $sp, $sp, 8     # restore stack pointer   
      jr $ra              # return    
  
  .globl  sad
  sad:    subu $sp, $sp, 32       # allocate stack space for largest function
      sw $s7, 28($sp)         # save $s7 value    
      sw $s6, 24($sp)         # save $s6 value
      sw $s5, 20($sp)         # save $s5 value
      sw $s4, 16($sp)         # save $s4 value
      sw $s3, 12($sp)         # save $s3 value
      sw $s2, 8($sp)          # save $s2 value
      sw $s1, 4($sp)          # save $s1 value
      sw $s0, 0($sp)          # save $s0 value
  
  
      #some code to be filled later
  
  
  
      lw $s7, 28($sp)         # restore original value of $s7 for caller
      lw $s6, 24($sp)         # restore original value of $s6 for caller
      lw $s5, 20($sp)         # restore original value of $s5 for caller
      lw $s4, 16($sp)         # restore original value of $s4 for caller
      lw $s3, 12($sp)         # restore original value of $s3 for caller
      lw $s2, 8($sp)          # restore original value of $s2 for caller
      lw $s1, 4($sp)          # restore original value of $s1 for caller
      lw $s0, 0($sp)          # restore original value of $s0 for caller
      addiu $sp, $sp, 32      # restore the caller's stack pointer
      jr $ra              # return to caller's code
  </code></pre>