* CPU非依存アセンブラ -(by [[K]], 2018.05.01) ** (1) 位置づけ -Essenでは、いきなりx86の機械語を出力してJITコンパイルするわけではない。 --(註:2013年に作っていたOSECPU-VMでは直接x86の機械語を生成して実行する仕組みを採用したが、そのせいで改良や最適化が難しくなっていた。) -Essenのプログラムはまず「CPU非依存アセンブラ」に変換され、そこからx86のアセンブラに変換され、最後にx86の機械語に変換される。 -多段式にすることでおそらくトータルでの変換速度は落ちるが、しかしそれぞれのレベルで最適化をする余地が生まれるので、JIT実行する際の速度はむしろ良くなると期待される。 ** (2) 基本文法 -どうせこのレイヤで人間が直接プログラムを書くことはほとんどないので、機械にとって都合のよい仕様を目指す。 -[1] 語の区切りはスペースかタブか改行(複数でもいい)。 -[2] C言語っぽい見た目。 -[3] しょせんはアセンブラなので、 d = a + b + c みたいに複数の演算が入るような式はアウト。x86ではLEA文で計算するテクニックがあるけど、そういう命令は生成しないということで切り捨てる。 -[3] しょせんはアセンブラなので、 d = a + b + c みたいに複数の演算が入るような式はアウト。x86ではLEA文で3項の和を計算するテクニックがあるけど、そういう命令は生成しないということで切り捨てる。 -[4] I32型の変数をいくつでも作れる。これらはメモリやレジスタに割り当てられることになるが、ひとまずそれを気にすることなく、自由に書いてよい。割り当てを気にせず使えるようにすることがこのレイヤの仕事なので。 -[5] このレイヤではポインタのチェックや演算のオーバーフローのチェックをしたりはしない。それはもっと上のレイヤで考慮して、その検査を含んだコードを出力する・・・つもりだったけど、このレイヤでチェックしたほうがいいのかな。少し悩む。 -[6] このレイヤでは構造体はサポートしない。 -[7] このレイヤでは配列アクセスはリード・ライトしかサポートしない。演算したければ単純変数に代入してから演算して、結果を配列に書き込む。 -ということで、例。 I32 a , b , c ; // コメントが書ける。 I32はInt32のこと。 // プログラム中で使われる変数の数が少ない場合、ローカル変数はすべてレジスタに割り当てられる。 // 宣言順に EAX, ECX, EDX, EBX, ESI, EDI になる。 a = 10 ; // MOV EAX,10 になる。 c = 1 ; // MOV EDX,1 になる。 b = a + c ; // MOV ECX,EAX; ADD ECX,EDXになる。 * こめんと欄 #comment