title: MIPS 32 bit, assembler: push and pop
body: <p>I'm having trouble with my code, MARS will not assemble it, because I use a wrong type of register for the <code>sw</code> instruction.</p>
  
  <p>Why cant I use this line</p>
  
  <pre><code>sw $so, 0($sp)
  </code></pre>
  
  <p>Is there something wrong with using s type register with <code>sw</code>?
  I want to save the value of <code>$so</code> on stack, how should I go about it?</p>
  
  <p>full code:</p>
  
  <pre><code>.data   
  .text
  f1:
      li $s0, 30
      addi $sp, $sp, -4
      sw $so, 0($sp)
      jal f2
      lw $v2, 0($v1)
      add $sp, $zero, $zero
      addi $sp, $sp, -4
      add $sp, $zero, $zero
      j Exit
  f2:
      addi $sp, $sp, -4
      sw $sp, 0($ra)
      jal f3
      lw $to, 0($vo)
      srl $t0, $to, 1
      add $to, $to, $to
      lw $ra, 0($sp)
      addi $sp, $sp, 4
      jr $ra
  f3:
      addi $vo, $so, 1
      jr $ra
  Exit: 
      result .asciiz "Value is "
      la $v2, result 
      syscall
  </code></pre>
  
  <p>Edit:</p>
  
  <p>thanks for the answers, I got things more correct, and now I have a problem at line 16 in my new code.
  What should happen before I save an address on stack, so that the following error won't appear?
  Error: </p>
  
  <blockquote>
    <p>line 16: Runtime exception at 0x00400028: Cannot write directly to text segment!0x00400010</p>
  </blockquote>
  
  <p>code:</p>
  
  <pre><code>.data
      result: .asciiz "Value is "
  .text
  f1:
      li $a0, 30          #n=30
      addi $sp, $sp, -4       #set sp back for save
      sw $a0, 0($sp)          #save a0 to stack
      jal f2              
      lw $a1, 0($v1)          
      add $sp, $zero, $zero
      addi $sp, $sp, -4
      add $sp, $zero, $zero
      j Exit
  f2:
      addi $sp, $sp, -4
      sw $sp, 0($ra)
      jal f3
      lw $t0, 0($v0)          #
      srl $t0, $t0, 1
      add $t0, $t0, $t0
      lw $ra, 0($sp)
      addi $sp, $sp, 4
      jr $ra
  f3:
      addi $v0, $a0, 1        #
      jr $ra
  Exit: 
      li $v0, 4
      la $a2, result 
      syscall
  </code></pre>