x86-64)のマシン語命令を生成するC++のクラスライブラリです。プログラム実行時に動的にアセンブルすることが可能です。・ヘッダファイルオンリーxbyak.hをインクルードするだけですぐ利用することができます。C++の枠組み内で閉じているため、外部アセンブラは不要です。32bit/64bit両対応です。Macなどで動作確認をしています。or_を使用してください。orなどを使いたい場合は-fno-operator-namesをgcc/clangに指定してください。-----------------------------------------------------------------------------◎準備xbyak.hxbyak_bin2hex.hこれらを同一のパスに入れてインクルードパスに追加してください。installで/usr/local/include/xbyakにコピーされます。16bitにキャストした値を使うように変更。`<winsock2.h>`をincludeしなくなったので必要なら明示的にincludeしてください。XBYAK_USE_MMAP_ALLOCATORがデフォルトで有効になりました。従来の方式にする場合はXBYAK_DONT_USE_MMAP_ALLOCATORを定義してください。従来のenumの値をとるにはintにキャストしてください。(古い)Reg32eクラスを(新しい)Reg32eとRegExpに分ける。例外なしモード追加XBYAK_NO_EXCEPTIONを定義してコンパイルするとgcc/clangで-fno-exceptionsオプションでコンパイルできます。エラーは例外の代わりに`Xbyak::GetError()`で通達されます。この値が0でなければ何か問題が発生しています。この値は自動的に変更されないので`Xbyak::ClearError()`でリセットしてください。`CodeGenerator::reset()`は`ClearError()`を呼びます。MmapAllocator追加これはUnix系OSでのみの仕様です。XBYAK_USE_MMAP_ALLOCATORを使うと利用できます。デフォルトのAllocatorはメモリ確保時にposix_memalignを使います。countを減らします。countの最大値は/proc/sys/vm/max_map_countに書かれています。デフォルトでは3万個ほどのXbyak::CodeGeneratorインスタンスを生成するとエラーになります。test/mprotect_test.cppで確認できます。これを避けるためにはmmapを使うMmapAllocatorを使ってください。AutoGrowモード追加これはメモリ伸長を動的に行うモードです。今まではXbyak::CodeGenerator()に渡したメモリサイズを超えると例外が発生していましたが、このモードでは内部でメモリを再確保して伸長します。getCode()を呼び出す前にジャンプ命令のアドレス解決をするためにready()関数を呼ぶ必要があります。ready()を呼んで確定するまではgetCurr()で得たポインタは無効化されている可能性があります。offsetで新しいポインタを取得してください。AutoGrowモードでは64bitモードの相対アドレッシング[rip]は非サポートです。x64アセンブラを記述します。そのメソッドを呼び出した後、getCode()メソッドを呼び出し、その戻り値を自分が使いたい関数ポインタに変換して利用します。・基本的にnasmの命令で括弧をつければよいです。onlyという形で指定します。サイズを指定する必要がない限りptrを使えばよいです。セレクター(セグメントレジスタ)をサポートしました。(注意)セグメントレジスタはOperandを継承していません。byteはメンバ変数です。intのつもりでdwordをtypedefしないでください。・AVXFMAについては簡略表記を導入するか検討中です(アイデア募集中)。xmm1*注意*デスティネーションの省略形はサポートされなくなりました。xmm3XBYAK_ENABLE_OMITTED_OPERANDを定義すると使えますが、将来はそれも非サポートになるでしょう。は新しいopmaskレジスタです。T_rz_saeを使ってください。k4`は意味が異なります。{1toX}の代わりにptr_bを使ってください。Xは自動的に決まります。一部の命令はメモリサイズを指定するためにxword/yword/zword(_b)を使ってください。setDefaultEncoding()でencoding省略時のEVEX/VEXを設定できます。・ラベルL(文字列);で定義します。ジャンプするときはその文字列を指定します。相対アドレスが8ビットに収まらない場合はT_NEARをつけないと実行時に例外が発生します。"L2");の様にラベルが表すアドレスをmovの即値として使えます。・hasUndefinedLabel()を呼び出して真ならジャンプ先が存在しないことを示します。コードを見直してください。("L2");...少しの命令の場合。outLocalLabel()で挟むことで局所化できます。outLocalLabel()は入れ子にすることができます。outLocalLabel()が無いと、".lp"ラベルの二重定義エラーになります。新しいLabelクラスによるジャンプ命令ジャンプ先を文字列による指定だけでなくラベルクラスを使えるようになりました。srcLabel)という命令も追加されました。label1);上記jmp命令はlabel1にジャンプします。srcLabelはL()により飛び先が確定していないといけません。dstLabelはL()により飛び先が確定していてはいけません。ラベルは`getAddress()`によりそのアドレスを取得できます。未定義のときは0が返ります。`retf()`をサポートします。サイズを明示するために`ptr`の代わりに`word|dword|qword`を利用してください。0);デフォルトコードサイズは4096(=DEFAULT_MAX_CODE_SIZE)バイトです。それより大きなコードを生成する場合はCodeGenerator()のコンストラクタに指定してください。CodeGenerator(8192){}...};またユーザ指定メモリをコード生成最大サイズと共に指定すると、CodeGeneratorは指定されたメモリ上にバイト列を生成します。補助関数として指定されたアドレスの実行属性を変更するCodeArray::protect()と与えられたポインタからアライメントされたポインタを取得するCodeArray::getAlignedAddress()も用意しました。userを参考にしてください。ALIGN_SIZE);・read/execモードデフォルトのCodeGeneratorはコンストラクト時にJIT用の領域をread/write/execモードに設定して利用します。コード生成時はread/writeでコード実行時にはread/execにしたい場合、次のようにしてください。JIT領域を実行AutoGrowの場合はreadyの代わりにreadyRE()を読んでください。JIT領域を実行setProtectModeRW()を呼ぶと領域が元のread/execモードに戻ります。その他詳細は各種サンプルを参照してください。-----------------------------------------------------------------------------◎マクロ32bit環境上でコンパイルするとXBYAK32が、64bit環境上でコンパイルするとXBYAK64が定義されます。gcc上ではXBYAK64_GCCが定義されます。x64)-----------------------------------------------------------------------------◎ライセンス修正された新しいBSDライセンスに従います。