LLPMLにブロックを実装して、変数のスコープが使えるようになりました。トップレベルのブロックではグローバル変数として.dataや.bssに、それ以下のブロックではローカル変数としてスタックに格納されます。
次はブロックを拡張して関数を実装する予定です。
x86命令の疑似コード
将来的に何段もネストした関数内関数をサポートするため、ブロックの頭でENTER命令を使用しています。インテルのマニュアルの疑似コードは入り組んでわかりにくかったため、32bit決め打ちで書き直して理解しました。
Enter(Size, NestingLevel) { Push(EBP); FrameTemp = ESP; if (NestingLevel > 0) { for (i = 1; i < NetsingLevel; i++) { EBP -= 4; Push([EBP]); } Push(FrameTemp); } EBP = FrameTemp; ESP = EBP - Size; } Leave() { ESP = EBP; Pop(EBP); }
PUSHとPOPはスタックポインタがどのタイミングで動くのかあやふやだったので、確認のために疑似コードにしてみました。
Push(SRC) { ESP -= 4; [ESP] = SRC; } Pop(DEST) { DEST = [ESP]; ESP += 4; }