iPhoneやAndroidなどで動くゲームエンジンであるCocos2dxではマルチプラットフォームを実現するためにゲームロジック部をC++で書くんだけど、スクリプト言語として軽量組み込み言語であるLuaやJavaScriptを使うこともできる。それも単なるインタプリタじゃなくてLuaJITやSpiderMonkeyを組み込んでいる。なのでスクリプト言語を使ったからといって速度的に大きなペナルティはない模様、すげえ!iPhoneやAndroidでCPU違っても動くんだろうか。
てことで、また瞬間的にJIT熱にうかされた。JITってどうやって作るのか全く知らないので、まずXbyakというものを触ってみた。そもそもx86のアーキテクチャもほとんど知らないので辛いんだけど、簡単なサンプルとして、定数を返す関数を作るクラスを生成する例:
|
コンパイルするにはg++で-fno-operator-names
オプションをつける必要がある(Xbyakで始めるx86(IA-32)入門(2-1) (mitsunari@cybozu labs))。
Xbyakでのコードの生成は、Xbyak::CodeGenerator
クラスを継承して、x86のニーモニックに似たメソッドでコードを組み立てて、getCode<関数の型>()
で取得して使うってのが流れ。本当はx86の32ビットか64ビットかなどで使う命令を変える必要があるみたいなんだけど、自分の環境でしか試してないため64bit GCC用のコードとなっている。戻り値はeax
レジスタに入れてやればよい。mov
命令でレジスタに即値、または他のレジスタの値を代入する。
次に引数を受け取る関数のテストとして、ある値を加算する関数を生成する:
class AdderFunc : public Xbyak::CodeGenerator { |
64bitのx86でのgccの呼出規約で、関数への整数の引数は1番目がedi
、以降esi
, edx
, ecs
, er8
, er9
…に渡されるらしい(gccでのレジスタ - x64 Assembly Language Programming)。
次は条件分岐を使う例として、階乗を求める関数を生成する:
class FactorialFunc : public Xbyak::CodeGenerator { |
ジャンプ命令は条件によっていろいろあって、ある値以上である場合はjg
となる(アセンブリ言語とx86機械語の対応表みたいなのってどこにありますか? 確かIntelの… - Yahoo!知恵袋より、intelの資料のIA-32 インテル® アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 A: 命令セット・リファレンス A-MおよびN-Z)。
C言語で書けば
int factorial(int edi) { |