←第3回のヒント | ↑目次 | →課題4.1,4.2のヒント
情報科学実験II コンパイラ作成
第2, 3回で間違いやすいところ
- ラベルのつけ方
- 論理否定(!)の他に、論理和(||)、論理積(&&)、if文、while文で、また場合によっては相等(==)、不相等(!=)でラベルが必要になります。これらのラベルも論理否定と同じように大域変数と局所変数を用いて、重複しないようにラベルを設定する必要があります。論理和とifでは3つ、相等、不相等、whileでは2つのラベルが必要になりますので、ラベルの個数だけ局所変数を用意する必要があります。
- 乗除算ルーチン
- こちらで用意した乗除算ルーチンでは$a0, $a1の積、商、剰余を求めます。乗算と除算では$v0に、剰余は$v1に戻ってきます。レジスタ名を取り違えないようにしてください。
- 文字列の比較
- 入出力関数の処理や、main関数を探すときに文字列の比較を行いますが、C言語で2つの文字列s, tを比較するにはstrcmp関数を使います。
(誤) s==t (正) !strcmp( s, t )
- 変数のアドレス
-
genCodeExprAssign, genCodeExprVarなどで、局所変数や引数に対してsw, lw命令でアクセスするメモリの$fpからの相対位置を指定しますが、それが誤っている場合があります。とくに、SymEntryPtr symが表す引数のオフセットはsym->belong->nParamとsym->noを使って求めます。
- In, Outの呼び出し方
- 指導書に記載されいてるgenCodeIn, genCodeOutでは、in(), out(x)はそれぞれ一般の関数と同様に呼ばれることを前提にしたコードが記載されています。したがって、呼び出す前にスタックポインタの値を4だけ減らしてから引数をpushし、呼び出した後にスタックポインタを引数の個数の4倍だけ増やす必要があります。
- 関数の後処理
-
指導書の通りにするのであれば、関数の後処理で返り値を返すためのアドレスの基準となるレジスタは$fpです。これを$spにすると予期しない場所にデータが書き込まれることで、予想しない動作になることがあります。また、$fpからのオフセットは指導書にある固定値16ではなく、引数の個数から計算して求める必要があります。
- リターン文の処理
-
stmtNodeのreturn文を処理する際に、式の評価後すぐにja $raとするケースが見られました。
- main関数
-
main関数を探す処理をせずに、指導書にあるF0005にjalするケースが見られました。
- 変数の番号
-
指導書では局所変数や引数の番号は1から開始することを前提としています。0からでもかまいませんが、構文解析で記号表を作る際に注意してください。
- 代入文の構文木
-
指導書の代入文の構文木では、代入される変数はsymメンバーに、代入すべき式はsub1メンバーに記載しています。代入される変数がsub1メンバーのsymメンバー、代入すべき式がsub2メンバーということでもかまいませんが、構文解析で記号表を作る際に注意してください。
トップページ