書こうとする度に、以前学んだことを忘れていることに気付く

  • gccの手続き呼び出し規約ではスタックフレームは6語(24バイト)以上確保することになっている。
  • スタックフレームは4語(16バイト)単位で確保するって聞いた。大学の講義で。

じゃあスタックフレームは最小でも32バイト確保しないといけないのかもしれない。
めんどくさいから確かめないけど、main関数でスタックフレームをケチって4バイトとかにしたらcore吐いて死んだりした記憶がある。

  • MIPS32の命令はきっと全部32bitの固定長。

全部適当なうろ覚え。よくわからん。

えーとレジスタは32bitだから、4バイトで1語。
なんか漠然とwebで資料探したくなったときにはgoogle:mips アセンブラ (講義資料|site:ac.jp)]とかすると有意なデータが多い気がする。と思ったが、あらためて[google:mips アセンブラで検索してみたらそうでもない気がした。この日記はそのS/N比を下げる存在だと思うけど別にいいや。

階乗関数を書いてみた。ここからはどこの関数も呼び出さない末端の関数なので、スタックフレームを確保せず、一時変数をくるくるループさせてみた。普通に動いた。

    .text		# 以下は命令列ですよ
.globl fact # factラベルはグローバル(外部から参照できる)
.ent fact # こっからfactルーチンですよと明記。書かなくてもいい(と思う)。enterの略かな
fact:
move $8, $4 # $4(第一引数)の内容を$8(一時変数)に

addu $9, $0, 1 # $0(常に値0を持つレジスタ)+1を$9(一時変数)に代入。ようするに$9=1
factloop:
beq $8, $0, factdone # $8=$0ならばfactdoneラベルの位置へ

mul $9, $9, $8 # $9*$8を$9に代入
subu $8, $8, 1 # $8-1を$9に代入
b factloop # 無条件でfactloopラベルに行く(branchの略)

factdone:
move $2, $9 # $9の内容を$2(返り値)に

j $31 # $31(戻り先アドレス)に移動(jump)
.end fact # ここでfactルーチン終了と明記。.entと対(だと思う)

test