小さいVMが動いた
とりあえずな感じのVMを実装して動かしてみた。扱える値はintのみ。
pushi(1) で1をスタックにpush。ref(0)でスタックの上から0番目を演算レジスタに読み込み。addi(1)で演算レジスタに1加算。say()で演算レジスタの中身を表示。jmpでラベルまでジャンプ。以下無限ループ。
ソースはこちら。http://unicus.ddo.jp/public/browser/tivi/trunk
#include "tivi.hpp" using namespace Tivi; int main(){ TiviAssembler tasm; tasm.pushi(1) .ref(0) .label("hoge") .addi(1) .say() .jmp("hoge") ; TiviVM vm(tasm); cout << "result: " << vm.run_program() << endl; return 0; }
小さいVMで mod 2 を実装してみた
1から20までの数の mod 2 を出力するプログラムを書いてみた。命令セットが加算しかないので、面倒なのです。
int main(){ TiviAssembler tasm; tasm.pushi(0) // push 0 to stack .ref(0) // load from stack to VAL .label("loop") .addi(1) // add 1 to VAL .say() // print current number .push() // remember current number // function call: mod2 .push() // arg for mod2 .call("mod2") .say() // print returned value .pop() // restore current value .compi(20) // compare current value with 20 .jmp_if("loop_end") .jmp("loop") .label("loop_end") .quit() // function mod2 .label("mod2") .pop() // load argument to VAL .label("mod2_itr") // main loop .compi(0) .jmp_if("mod2_end") .compi(1) .jmp_if("mod2_end") .addi(-2) // add -2 to VAL .jmp("mod2_itr") .label("mod2_end") .ret() ; TiviVM vm(tasm); cout << "result: " << vm.run_program() << endl; return 0; }
コメントで質問があったので追記。TracのURLのままではsvnからチェックアウトできないので、チェックアウトしたい人は以下のURLを使ってくださいまし。