diff --git a/readme.txt b/readme.txt index aea8431..7885d5f 100644 --- a/readme.txt +++ b/readme.txt @@ -1,241 +1,241 @@ - - C++x86(IA-32), x64(AMD64, x86-64) JIT⎢⎻㎳妫 Xbyak version 2.24 - ------------------------------------------------------------------------------ -莦ꎦ - -Ꭿx86, x64(AMD64, x86-64)Ꭾ夹㎳¿轎ȡⵤ++Ꭾ⎯㎩⎹㎩⎤妫㎪Ꭷ񎼎 -妯⎰㎩㎠ꎡᎫᎫ⎢⎻㎳妭墪羱㎽Ꭷ񎼎 - ------------------------------------------------------------------------------ -鲻 - -㎻夣⎤㎫⎪㎳㎪㎼ - xbyak.h夦㎳⎯㎫㎼墢墩莩墪墩񎼎 - C++Ꭾ墩Ꭶ玤릪⎢⎻㎳妫Ꭿ躺ꎦ墩񎼎 - 32bit/64bit躎걎墩񎼎 - 걎㎼㎢⎯:鎹쪎轎86, MMX/MMX2/SSE/SSE2/SSE3/SSSE3/SSE4/FPU(躀㎨) - -㎻Windows Xp(32bit, 64bit), Vista/Linux(32bit, 64bit)/Intel Mac걎 - Windows Xp躴墩ᎯVC2005 Express Ed., VC2008 - Windows Vista - Linux (kernel 2.4.32)躴墩Ꭿgcc 4.3.0, CentOS 5.1躴墩Ꭿgcc 4.1.2 - Intel Mac - ᎪᎩᎧ掽鎢墨񎼎 - - gccᎧᎯand, or, xorᎪᎩ莼鎮玭墪墨𩎣Ꭶ墡񎼌 --fno-operator-names⎪夹㎧㎳ꎿꎠ墨⎳㎳夦㎫墨墢 - ------------------------------------------------------------------------------ -莺 -xbyak.h -xbyak_bin2hex.h -xbyak_mnemonic.h -掸Ꭾ夻Ꭻ厥墨⎤㎳⎯㎫㎼⎹Ꭻꎠ墨墢 - -LinuxᎧᎯmake installᎧ/usr/local/include/xbyakᎫ⎳妾Ꮎ񎼎 ------------------------------------------------------------------------------ -쵕 - -Xbyak::CodeGenerator ⎯㎩⎹鎶񎼸Ꭾ⎯㎩⎹㎡⎽墩x86, x64⎢⎻㎳妫 -ꎿ񎼼Ꭾ㎡⎽¾Ꮃ玺墡񎼷etCode()㎡⎽¾Ꮃ玺񎼸Ꭾ莻 -瀎ꮬ迎墡̤夦㎳⎿Ꭻꦲ墨莩񎼼夤⎻㎳妭⎨㎩㎼Ꭿ玤 -ᎫާᎾ(cf. main.cpp) - -㎻ꡎ墭nasmᎮ轎Ꭷ뎬꾎墦ᎰᎧ񎼎 - -mov eax, ebx --> mov(eax, ebx); -inc ecx inc(ecx); -ret --> ret(); - -㎻⎢妮夹㎳⎰ - -(ptr|dword|word|byte) [base + index * (1|2|4|8) + displacement] -Ꭸ꿎Ꭷ玮Ꮎ񎼼夷⎤⎺玿ꎦᎪtr掽墲Ꭷ񎼎 -⎻㎬⎯⎿Ꭿ⎵妾Ꭶ - -mov eax, [ebx+ecx] --> mov (eax, ptr[ebx+ecx]); -test byte [esp], 4 --> test (byte [esp], 4); - -(쵎) dword, word, byteᎯ⎯㎩⎹ꦲʲᎧ񎼼玾墥Ꭶ墪墲unsigned intᎮ -ᎤᎧdwordypedef墬墩墢 - -㎻㎩妭 - -L(玭); -Ꭷ鎾񎼼夺㎣㎳墪墱墰玭Ꮎ񎼼玾̻骩羱㎽Ꭷ -걎⎢妮⎹8墭墬玠墱T_NEAR墦墬墪ꎡᎫ玤 -񎼎 - -㎻hasUndefinedLabel()¾Ꮃ玺墨墬夺㎣㎳玭ت墬Ꭸ鎤񎼎 -⎳㎼ֶ墨墢 - -L("L1"); - jmp ("L1"); - - jmp ("L2"); - ... - Ꭾ轎Ꭾꢎ񎼎 - ... -L("L2"); - - jmp ("L3", T_NEAR); - ... - 촎곎Ꭾ轎玠 - ... -L("L3"); - -<Ȫ> - -1. MASM㎩⎤⎯Ꭺ@@, @f, @b夷妾 - - L("@@"); // - jmp("@b"); // jmp to - jmp("@f"); // jmp to - L("@@"); // - jmp("@b"); // jmp to - -2. ㎩妭Ꭾ곀 - -妬⎪墩ꩶ妫妭nLocalLabel(), outLocalLabel()Ꭷ墪Ꭷ곀墩񎼎 - -void func1() -{ - inLocalLabel(); - L(".lp"); // - ... - jmp(".lp"); // jmpt to - outLocalLabel(); -} - -void func2() -{ - L(".lp"); // - func1(); - jmp(".lp"); // jmp to -} - -躴ꎨ夷㎳妭ᎧᎯinLocalLabel(), outLocalLabel()騣墪 -".lp"㎩妭Ꭾ輸鎾⎨㎩㎼ᎫᎪ񎼎 - -㎻Xbyak::CodeGenerator()⎳㎳⎹妫⎯⎿⎤㎳⎿天㎼⎹ - -@param maxSize [in] ⎳㎼ȡꦎ⎵⎤⎺(⎩㎫2048byte) -@param userPtr [in] ㎦㎼⎶玮妣㎢㎪ - -CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0); - -⎩㎫夵㎼夷⎤⎺Ꭿ2048(=DEFAULT_MAX_CODE_SIZE)夦墩񎼎 -ꦎ墬⎳㎼ꢎ墱CodeGenerator()Ꭾ⎳㎳⎹妫⎯⎿Ꭻ玮Ꭶ墢 - -class Quantize : public Xbyak::CodeGenerator { -public: - Quantize() - : CodeGenerator(8192) - { - } - ... -}; - -# Ꭻ墡ᎻᎮᎠ玮ꎡ玱耎Ꭾ墩墥ᎦᎾ - -Ꮎ妨㎼⎶玮妣㎢㎪夵㎼ȡꦎ⎵⎤⎺Ꭸ厱Ꭻ玮墪odeGeneratorᎯ -玮墡㎡㎢㎪躴墭夦ȡᎾ񎼎 - -⎵妾̤Ꭸ墨玮墡⎢妮⎹Ꭾꎡ玱耎玤ֶCodeArray::protect()Ꭸ -躼⎤㎳⎿⎢㎩⎤㎡㎳墡夦㎳⎿ⵤodeArray::getAlignedAddress() -ȪᎾ墡ꎩᎯsample/test0.cppᎮuse memory allocated by user墭 -墨墢 - -/** - change exec permission of memory - @param addr [in] buffer address - @param size [in] buffer size - @param canExec [in] true(enable to exec), false(disable to exec) - @return true(success), false(failure) -*/ -bool CodeArray::protect(const void *addr, size_t size, bool canExec); - -/** - get aligned memory pointer -*/ -uint8 *CodeArray::getAlignedAddress(uint8 *addr, size_t alignedSize = ALIGN_SIZE); - -墰ꎩᎯ鎨⎵㎳妭厧墨墢 ------------------------------------------------------------------------------ -⎯㎭ - -32bitꤦ掸墩⎳㎳夦㎫ᎨXBYAK32񎼌64bitꤦ掸墩⎳㎳夦㎫ᎨXBYAK64 -鎾Ꮎ񎼼墭64bitꤦ掸墩ᎯWindowsᎪⱹBYAK64_WINcc躴墩ᎯXBYAK64_GCC -玮鎾Ꮎ񎼎 - ------------------------------------------------------------------------------ -掽 - -test0.cpp ; 墬(x86, x64) -quantize.cpp ; 鎲鎮墰JIT⎢⎻㎳妭Ꭻ玭Ꭾ(x86) -calc.cpp ; 躼玤뎠玼⎢⎻㎳妭墨ꎡ(x86, x64) - boost(http://www.boost.org/)玿ꎦ -bf.cpp ; JIT Brainfuck(x86, x64) - ------------------------------------------------------------------------------ -莳 - -MMX/SSE轎ᎯᎻᎼ厨Ꭶꎣ墨3D Now!轎񎼸掸㎨Ꭾ鎹찴墬 -轎Ꭿ餻ᎧᎯꎣ墨PUᎮ80bit췎现ʲᎯ⎵妾Ꭶ - -ꎦ墲뀎墢 - ------------------------------------------------------------------------------ -妫⎤⎻㎳⎹ - -쯎̲BSD㎩⎤⎻㎳⎹ᎫᎾ񎼎 -http://www.opensource.jp/licenses/bsd-license.html - -sample/{echo,hello}.bfᎯ http://www.kmonos.net/alang/etc/brainfuck.php -墡Ꭰ墡 - ------------------------------------------------------------------------------ -玱쯎 - -2010/04/16 ver 2.24 change the prototype of rewrite() method -2010/04/15 ver 2.23 fix align() and xbyak_util.h for Mac -2010/02/16 ver 2.22 fix inLocalLabel()/outLocalLabel() -2009/12/09 ver 2.21 support cygwin(gcc 4.3.2) -2009/11/28 ver 2.20 FPUᎮ躀㎨轎⎵妾 -2009/06/25 ver 2.11 64bit㎢㎼墩Ꭾ mov(qword[rax], imm); 쯎(thanks to Martin) -2009/03/10 ver 2.10 jmp/call reg64ᎮʹᎪREG.WҦ -2009/02/24 ver 2.09 movq reg64, mmx/xmm; movq mmx/xmm, reg64ꎠ -2009/02/13 ver 2.08 movd(xmm7, dword[eax])0x66Ꭸ⎰쯎(thanks to Gabest) -2008/12/30 ver 2.07 call()Ꭾ걎⎢妮⎹8bit轎躶墰Ꭸ墰夲쯎(thanks to kato) -2008/09/18 ver 2.06 @@, @f, @bᎨ㎩妭Ꭾ곀莩ꦿꎠ(thanks to nobu-q) -2008/09/18 ver 2.05 ptr [rip + 32bit offset]⎵妾(thanks to 缪(Dango-Chu)) -2008/06/03 ver 2.04 align()Ꭾ夭夻쯎ov(ptr[eax],1);ᎪᎩ太㎩㎼Ꭻ -2008/06/02 ver 2.03 ㎦㎼⎶鎾㎡㎢㎪⎤㎳⎿天㎼⎹⎵妾 -2008/05/26 ver 2.02 protect()(on Linux)Ꭷ躺莭Ꭺ𪎭墭ᎪᎨ墰掿쯎(thanks to sinichiro_h) -2008/04/30 ver 2.01 cmpxchg16b, cdqeꎠ -2008/04/29 ver 2.00 x86/x64-64窮 -2008/04/25 ver 1.90 x86Ў厬 -2008/04/18 ver 1.12 ⎳㎼ʶ -2008/04/14 ver 1.11 ⎳㎼ʶ -2008/03/12 ver 1.10 bsf/bsrꎠ(Ꭶ墡) -2008/02/14 ver 1.09 sub eax, 123416bit㎢㎼墩玺墨墡Ꭾ掿쯎(thanks to Robert) -2007/11/05 ver 1.08 lock, xadd, xchgꎠ -2007/11/02 ver 1.07 SSSE3/SSE4걎(thanks to 缪(Dango-Chu)) -2007/09/25 ver 1.06 call((int)夦㎳⎿); jmp((int)夦㎳⎿);Ꭾ⎵妾 -2007/08/04 ver 1.05 쯎 -2007/02/04 ̻ᎸᎮ⎸㎣㎳墩T_NEAR墦墬墪墭8bit걎⎢妮⎹Ꭻ厥墬 - ꢎ墭玤Ꭺ⎰Ꭾ쯎 -2007/01/21 [disp]Ꭾ꿎Ꭾ⎢妮⎹Ꭾ夲쯎 - mov (eax|ax|al, [disp]); mov([disp], eax|ax|al);ᎮꎡᎸ -2007/01/17 web妾⎸ -2007/01/04 厬ꩋ - ------------------------------------------------------------------------------ -莨 - -콶ȡ(MITSUNARI Shigeo, herumi at nifty dot com) - ---- -$Revision: 1.56 $ -$Date: 2010/04/16 11:58:22 $ + + C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak version 2.24 + +----------------------------------------------------------------------------- +◎概要 + +これはx86, x64(AMD64, x86-64)のマシン語命令を生成するC++のクラスライブラリです. +プログラム実行時に動的にアセンブルすることが可能です. + +----------------------------------------------------------------------------- +◎特徴 + +・ヘッダファイルオンリー + xbyak.hをインクルードするだけですぐ利用することができます. + C++の枠組み内で閉じているため,外部アセンブラは不要です. + 32bit/64bit両対応です. + 対応ニーモニック:特権命令除くx86, MMX/MMX2/SSE/SSE2/SSE3/SSSE3/SSE4/FPU(一部) + +・Windows Xp(32bit, 64bit), Vista/Linux(32bit, 64bit)/Intel Mac対応 + Windows Xp上ではVC2005 Express Ed., VC2008 + Windows Vista + Linux (kernel 2.4.32)上ではgcc 4.3.0, CentOS 5.1上ではgcc 4.1.2 + Intel Mac + などで動作確認をしています. + +※ gccではand, or, xorなどを演算子として解釈してしまうため, +-fno-operator-namesオプションを追加してコンパイルしてください. + +----------------------------------------------------------------------------- +◎準備 +xbyak.h +xbyak_bin2hex.h +xbyak_mnemonic.h +これらを同一のパスに入れてインクルードパスに追加してください. + +Linuxではmake installで/usr/local/include/xbyakにコピーされます. +----------------------------------------------------------------------------- +◎文法 + +Xbyak::CodeGenerator クラスを継承し,そのクラスメソッド内でx86, x64アセンブラを +記述します.そのメソッドを呼び出した後,getCode()メソッドを呼び出し,その戻 +り値を自分が使いたい関数ポインタに変換して利用します.アセンブルエラーは例外 +により通知されます(cf. main.cpp). + +・基本的にnasmの命令で括弧をつければよいです. + +mov eax, ebx --> mov(eax, ebx); +inc ecx inc(ecx); +ret --> ret(); + +・アドレッシング + +(ptr|dword|word|byte) [base + index * (1|2|4|8) + displacement] +という形で指定します.サイズを指定する必要がない限りptrを使えばよいです. +セレクタはサポートしていません. + +mov eax, [ebx+ecx] --> mov (eax, ptr[ebx+ecx]); +test byte [esp], 4 --> test (byte [esp], 4); + +(注意) dword, word, byteはクラス変数です.従ってたとえばunsigned intの +つもりでdwordをtypedefしないでください. + +・ラベル + +L(文字列); +で定義します.ジャンプするときはその文字列を指定します.後方参照も可能ですが, +相対アドレスが8ビットに収まらない場合はT_NEARをつけないと実行時に例外が発生 +します. + +・hasUndefinedLabel()を呼び出して真ならジャンプ先が存在しないことを示します. +コードを見直してください. + +L("L1"); + jmp ("L1"); + + jmp ("L2"); + ... + 少しの命令の場合. + ... +L("L2"); + + jmp ("L3", T_NEAR); + ... + 沢山の命令がある場合 + ... +L("L3"); + +<応用編> + +1. MASMライクな@@, @f, @bをサポート + + L("@@"); // + jmp("@b"); // jmp to + jmp("@f"); // jmp to + L("@@"); // + jmp("@b"); // jmp to + +2. ラベルの局所化 + +ピリオドで始まるラベルをinLocalLabel(), outLocalLabel()で挟むことで局所化できます. + +void func1() +{ + inLocalLabel(); + L(".lp"); // + ... + jmp(".lp"); // jmpt to + outLocalLabel(); +} + +void func2() +{ + L(".lp"); // + func1(); + jmp(".lp"); // jmp to +} + +上記サンプルではinLocalLabel(), outLocalLabel()が無いと, +".lp"ラベルの二重定義エラーになります. + +・Xbyak::CodeGenerator()コンストラクタインタフェース + +@param maxSize [in] コード生成最大サイズ(デフォルト2048byte) +@param userPtr [in] ユーザ指定メモリ + +CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0); + +デフォルトコードサイズは2048(=DEFAULT_MAX_CODE_SIZE)バイトです. +それより大きなコードを生成する場合はCodeGenerator()のコンストラクタに指定してください. + +class Quantize : public Xbyak::CodeGenerator { +public: + Quantize() + : CodeGenerator(8192) + { + } + ... +}; + +# 動的にしたほうがよいのだが実行属性の管理が面倒でやってません…. + +またユーザ指定メモリをコード生成最大サイズと共に指定すると,CodeGeneratorは +指定されたメモリ上にバイト列を生成します. + +サポート関数として指定されたアドレスの実行属性を変更するCodeArray::protect()と +与えられたポインタからアライメントされたポインタを取得するCodeArray::getAlignedAddress() +も用意しました.詳細はsample/test0.cppのuse memory allocated by userを参考に +してください. + +/** + change exec permission of memory + @param addr [in] buffer address + @param size [in] buffer size + @param canExec [in] true(enable to exec), false(disable to exec) + @return true(success), false(failure) +*/ +bool CodeArray::protect(const void *addr, size_t size, bool canExec); + +/** + get aligned memory pointer +*/ +uint8 *CodeArray::getAlignedAddress(uint8 *addr, size_t alignedSize = ALIGN_SIZE); + +その他詳細は各種サンプルを参照してください. +----------------------------------------------------------------------------- +◎マクロ + +32bit環境上でコンパイルするとXBYAK32が,64bit環境上でコンパイルするとXBYAK64が +定義されます.さらに64bit環境上ではWindowsならXBYAK64_WIN,gcc上ではXBYAK64_GCC +も定義されます. + +----------------------------------------------------------------------------- +◎使用例 + +test0.cpp ; 簡単な例(x86, x64) +quantize.cpp ; 割り算のJITアセンブルによる量子化の高速化(x86) +calc.cpp ; 与えられた多項式をアセンブルして実行(x86, x64) + boost(http://www.boost.org/)が必要 +bf.cpp ; JIT Brainfuck(x86, x64) + +----------------------------------------------------------------------------- +◎注意 + +MMX/SSE命令はほぼ全て実装されていますが,3D Now!命令や,一部の特殊な +命令は現時点では実装されていません.FPUの80bit浮動小数はサポートしていません. + +何かご要望があればご連絡ください. + +----------------------------------------------------------------------------- +◎ライセンス + +修正された新しいBSDライセンスに従います. +http://www.opensource.jp/licenses/bsd-license.html + +sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から +いただきました. + +----------------------------------------------------------------------------- +◎履歴 + +2010/04/16 ver 2.24 change the prototype of rewrite() method +2010/04/15 ver 2.23 fix align() and xbyak_util.h for Mac +2010/02/16 ver 2.22 fix inLocalLabel()/outLocalLabel() +2009/12/09 ver 2.21 support cygwin(gcc 4.3.2) +2009/11/28 ver 2.20 FPUの一部命令サポート +2009/06/25 ver 2.11 64bitモードでの mov(qword[rax], imm); 修正(thanks to Martinさん) +2009/03/10 ver 2.10 jmp/call reg64の冗長なREG.W削除 +2009/02/24 ver 2.09 movq reg64, mmx/xmm; movq mmx/xmm, reg64追加 +2009/02/13 ver 2.08 movd(xmm7, dword[eax])が0x66を落とすバグ修正(thanks to Gabestさん) +2008/12/30 ver 2.07 call()の相対アドレスが8bit以下のときのバグ修正(thanks to katoさん) +2008/09/18 ver 2.06 @@, @f, @bとラベルの局所化機能追加(thanks to nobu-qさん) +2008/09/18 ver 2.05 ptr [rip + 32bit offset]サポート(thanks to 団子厨(Dango-Chu)さん) +2008/06/03 ver 2.04 align()のポカミス修正.mov(ptr[eax],1);などをエラーに +2008/06/02 ver 2.03 ユーザ定義メモリインタフェースサポート +2008/05/26 ver 2.02 protect()(on Linux)で不正な設定になることがあるのを修正(thanks to sinichiro_hさん) +2008/04/30 ver 2.01 cmpxchg16b, cdqe追加 +2008/04/29 ver 2.00 x86/x64-64版公開 +2008/04/25 ver 1.90 x86版β公開 +2008/04/18 ver 1.12 コード整理 +2008/04/14 ver 1.11 コード整理 +2008/03/12 ver 1.10 bsf/bsr追加(忘れていた) +2008/02/14 ver 1.09 sub eax, 1234が16bitモードで出力されていたのを修正(thanks to Robertさん) +2007/11/05 ver 1.08 lock, xadd, xchg追加 +2007/11/02 ver 1.07 SSSE3/SSE4対応(thanks to 団子厨(Dango-Chu)さん) +2007/09/25 ver 1.06 call((int)関数ポインタ); jmp((int)関数ポインタ);のサポート +2007/08/04 ver 1.05 細かい修正 +2007/02/04 後方へのジャンプでT_NEARをつけないときに8bit相対アドレスに入らない + 場合に例外が発生しないバグの修正 +2007/01/21 [disp]の形のアドレス生成のバグ修正 + mov (eax|ax|al, [disp]); mov([disp], eax|ax|al);の短い表現選択 +2007/01/17 webページ作成 +2007/01/04 公開開始 + +----------------------------------------------------------------------------- +◎著作権者 + +光成滋生(MITSUNARI Shigeo, herumi at nifty dot com) + +--- +$Revision: 1.56 $ +$Date: 2010/04/16 11:58:22 $