手続き内で一時レジスタや,退避レジスタを使用する際には,
手続きに入る前にあらかじめ,スタックにレジスタの中身のデータを退避する必要がある.
例題「他の手続きを呼び出さない手続きのコンパイル」では,Cの手続きをMIPSコードにコンパイルする様子を使って説明がされている.
そのときのCコードは下記のようなもの
int leaf_example(int g, int h, int i, int j) { int f; f = (g + h) - (i + j); return f; }
このコードをMIPSコードに変換すると下記のようになる(と本に書いてある)
leaf_example: # スタックに3語分スペースをとる addi $sp, $sp, -12 sw $t1, 8($sp) sw $t0, 4($sp) sw $s0, 0($sp) add $t0, $a0, $a1 add $t1, $a2, $a3 sub $s0, $t0, $t1 add $v0, $s0, $zero lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) # スタックから3語分スペースを除く addi $sp, $sp, 12 jr $ra
ポイントはスタックは高いアドレスから低いアドレスに向かい伸びること.
つまりスタックにデータをプッシュするときには,$spを減算し,
スタックからデータをぽっぷするときには,$spを加算するということである.