私は、x86アーキテクチャ用の命令のサブセット用のシミュレータを実装したいと考えています。バイナリが与えられたら、それを逆アセンブルして命令上のシミュレーションを実行したいと思います。そのためには、制御命令、算術命令または論理命令のいずれであるかを決定するために命令の特定のビットを見る必要があり、それに基づいて、残りのビットを調べることによって演算のパラメータを導出しなければならない。これを実装するための明白かつ苦痛な方法の1つは、ネストされたif-else/switch-caseステートメントを使用することです。誰かがこれを実装するためのより良い方法を提案できますか?x86のサブセット用のシミュレータの実装
答えて
ルックアップテーブルは、おそらくstd::map
の形式で使用します。
何百万回も繰り返し実行できるものについては、 'map'よりもパフォーマンスに少し興味があると思います。少なくとも、ハッシュテーブルが望ましいでしょうが、それでもおそらく最善の選択ではありません。 – StilesCrisis
翻訳の出力をキャッシュする場合、ネストされたif/elseタイプの構文を使用すると問題はありません。シミュレーションを実行している場合は、プログラム内のすべての静的命令から動的命令が比較的少なくなります。したがって、パフォーマンスの最適な最適化は、変換の出力をキャッシュし、動的命令が実行されたときに再利用することです。最終的にキャッシュがいっぱいになるので、新しいエントリについてはクリアする必要があります。しかし、最初に翻訳を行う本当に高速な方法を考え出すのではなく、何らかの形で翻訳をキャッシュする方が意味があります。
例として、QEMUは、パフォーマンスに最適化されたさまざまなターゲットをサポートするエミュレータです。あなたは、彼らがここにx86命令を変換する方法を見ることができます。
https://github.com/qemu/QEMU/blob/master/target-i386/translate.c#L4076
QEMUは、すべての命令のためにこれをしなかった場合のパフォーマンスが非常に遅くなります。しかし、結果をキャッシュしてから、命令が最初に翻訳されるときに複雑なケース・ステートメントがあることはそれほど重要ではありません。
x86エミュレータのソースを見れば、すでに完全に書かれています。
ここでは、試してみてください一つだ:http://www.dosbox.com/wiki/BuildingDOSBox#1._Grab_the_source
はこれがうまくいかない場合は、私に教えてください。そこから選ぶべきたくさんがあります。
通常、エミュレータを使用すると、オペコードのスイッチが移動する方法の1つになると思います。もう1つの良いアプローチは、命令の最初のバイトに対応する256エントリの関数ポインタの配列です。これは、巨大なスイッチやブロックよりも少し離れています。もちろん、必要に応じて関数を再利用することもできます。
- 1. マルチメッセージMSIはLinux/x86上に実装されていますか?
- 2. Windows用のブーストミューテックスの実装
- 3. ウェブページ用のツールバーの実装
- 4. R data.tableサブセットのサブセット
- 5. 屋内ナビゲーション用のSteerPath SDK実装の実装方法
- 6. Android用Admobの実装
- 7. ViewHolderの実装と使用
- 8. XcodeのiOS用WebKit実装
- 9. box.net用WebHookの実装
- 10. .NET用OSGiの実装
- 11. System.Runtime.Caching.MemoryCacheの汎用実装
- 12. リストのアレイベースの実装(カーソルの実装)
- 13. x86/x64アーキテクチャ用のSQLite dll
- 14. XMLドキュメントインターフェイスの実装とクラスの実装
- 15. iPhone用のセキュアなリモートパスワードの実装
- 16. .Net用のY-モデムの実装
- 17. OpenSSLのC++での実装を使用
- 18. JSP/Liferay用のJqueryプログレスバーの実装
- 19. Windows用のMacスペースの実装
- 20. POCO用のシンプルなキャッシュの実装
- 21. デスクトップアプリケーションでのJPA実装の使用
- 22. C/C++用のMarkdownの実装
- 23. .NETコア用のIWebProxy実装の場所
- 24. クライアントサーバアプリケーション用のプロトコルの実装と設計
- 25. ビジターカウンターの実装
- 26. プロダクトキーの実装
- 27. ハッシュコードの実装
- 28. セットの実装
- 29. safe_ptrの実装
- 30. BeanFactoryの実装
基本的にswitch-caseステートメントが必要ですが、それほど必要ではありません。ルックアップテーブルにチェックインします。バイトを取得し、そのバイトの値のハンドラを呼び出し、ハンドラがオペランドを読み込んでリターンし、繰り返します。 – ssube