私は実際のx86アセンブリ出力をC#プログラム(CLRバイトコード命令ではありません)で表示することに興味があります。これを行う良い方法はありますか?JIT出力を取得する
答えて
SOS/SOSEXでWinDbgを使用し、x86コードがメソッドテーブルにJITされていることを確認してから、u
コマンドで実際のアンアセンブリを確認してください。したがって、実際のコードが表示されます。
ここで述べた他のものと同様に、ngenを使用すると、実際のJITコンパイル結果と正確に一致しないコードを参照することができます。 Visual Studioでは、JITのコンパイルはデバッガが存在するかどうかに大きく依存するため、可能です。
UPD:若干の説明。 WinDbgもデバッガですが、ネイティブです。
Hereこのテクニックについて詳しく読むことができます。
Visual Studioでアプリケーションをデバッグしているときに、停止したコード(ブレークポイントを使用)を右クリックし、[逆アセンブリに移動]をクリックします。ネイティブ命令でデバッグできます。
ディスク上の* .exeファイルを使用している場合は、NGenを使用してネイティブ出力を生成してから逆アセンブルすることができます(これは決して試したことがないので動作するとは限りません)。ここで
は、C#で書かれた簡単な算術演算からいくつかのサンプルオペコードです:
int x = 5; mov dword ptr [ebp-40h],5 int y = 6; mov dword ptr [ebp-44h],6 int z = x + y; mov eax,dword ptr [ebp-40h] add eax,dword ptr [ebp-44h] mov dword ptr [ebp-48h],eax
あなたが(ブレークポイントを配置し、その後、Dissassemblyウィンドウを表示してAltキー+ Ctrlキー+ DをVisual Studioのデバッガを使用することができます)またはNative Image Generator Tool(ngen.exe)を試してください。
メモリダンプを実行できます。ただし、メモリ内のコードには必ずしもすべてのメソッドが含まれているわけではありません。
ngenは、AOT、またはAhead-of-Timeコード生成を実行します。これは、JITコードとは異なる場合があります。
@IvanDanilov answeredとして、WinDbgとSOSを使用できます。ウォークスルーを提供するために私は別に答えています。
using System;
namespace TestArrayCompare
{
class Program
{
static bool AreEqual(byte[] a1, byte[] a2)
{
bool result = true;
for (int i = 0; i < a1.Length; ++i)
{
if (a1[i] != a2[i])
result = false;
}
return result;
}
static void Main(string[] args)
{
byte[] a1 = new byte[100];
byte[] a2 = new byte[100];
if (AreEqual(a1, a2))
{
Console.WriteLine("`a1' equals `a2'.");
}
else
{
Console.WriteLine("`a1' does not equal `a2'.");
}
}
}
}
手順:
- 開くWinDbgのこの例では
は、IからAreEqual()メソッドの分解を表示します。 「ファイル」メニューから「実行可能ファイルを開く...」を選択します。 EXE(私の場合は
C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release\TestArrayCompare.exe
)の場所を参照してください。 PDBファイルを含むディレクトリをシンボルパスに追加します。
clr.dll
でg
- : 'GO' コマンドを実行して続行
sxe ld:clr
:たとえば:
clr.dll
を介してロードされたときのWinDbgのコマンドウィンドウで.sympath "C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release"
、ブレークポイントを設定ModLoad、load SOS:
.loadby sos clr
BPMDを実行すると、 shを分解して見てください。たとえば:
0:000> !BPMD TestArrayCompare.exe TestArrayCompare.Program.AreEqual Adding pending breakpoints...
は 'GO' コマンドを実行して、もう一度続行:
g
実行Name2EEメソッドの記述を参照してください。たとえば:
0:000> !Name2EE TestArrayCompare.exe TestArrayCompare.Program.AreEqual Module: 00a62edc Assembly: TestArrayCompare.exe Token: 06000001 MethodDesc: 00a637a4 Name: TestArrayCompare.Program.AreEqual(Byte[], Byte[]) Not JITTED yet. Use !bpmd -md 00a637a4 to break on run.
は「まだJITコンパイルなし」のラインでBPMDコマンドを実行します。たとえば:
0:000> !bpmd -md 00a637a4 MethodDesc = 00a637a4 Adding pending breakpoints...
は再び続行:
g
あなたはコマンドウィンドウで "JITコンパイルを..." が表示されるはずです。 Name2EEコマンドを再実行して、JITコードのアドレスを確認します。たとえば:
0:000> !Name2EE TestArrayCompare.exe TestArrayCompare.Program.AreEqual Module: 00a62edc Assembly: TestArrayCompare.exe Token: 06000001 MethodDesc: 00a637a4 Name: TestArrayCompare.Program.AreEqual(Byte[], Byte[]) JITTED Code Address: 00b500c8
が記載されたコードのアドレスから始まる、分解し
u
コマンドを使用します。例えば:0:000> u 00b500c8 L20 00b500c8 55 push ebp 00b500c9 8bec mov ebp,esp 00b500cb 57 push edi 00b500cc 56 push esi ...
(上記の場合、私は、Windows 8.1 SDKからのWinDbg 6.3.9600.17200 X86を使用した。)
一つ便利参照はSOS.dll (SOS Debugging Extension) reference page on MSDNあります。
- 1. .NET jitコンパイラログを取得する
- 2. jitリポジトリのjsonリストを取得するには?
- 3. 奇妙な出力を取得する
- 4. コマンドプロンプト出力を取得する方法
- 5. リモートハドソンビルドの出力を取得する
- 6. Groovyでプロセス出力を取得する
- 7. PowerShellでSystem.Object []出力を取得する
- 8. Androidオーディオ出力を取得
- 9. 出力を取得し、
- 10. 取得コンソール出力は
- 11. 式出力の取得
- 12. インチの出力の取得
- 13. コマンド出力パラメータの取得
- 14. adbシェルの入力keyeventで出力を取得するには?
- 15. 出力の次の行に入力を取得する
- 16. 入力ファイルの出力ファイル形式を取得する方法
- 17. NetBeansの出力タブから入力を取得する方法
- 18. ロジックアプリのアクション入力/出力を取得するRESTエンドポイント
- 19. JavaはいつJITコンパイラを取得しましたか?
- 20. プロセスを開いて出力を取得し、別のプロセスを開き、出力を取得します。
- 21. PHPのcurlから出力を取得
- 22. Popenからリアルタイム出力を取得
- 23. ループ出力からWebSQLデータを取得
- 24. VB.netでシェルコマンドの出力を取得
- 25. CodeIgniterでWHOIS出力を取得
- 26. XMLとDOMの#text出力を取得
- 27. 変数findstrの出力を取得
- 28. mysqlクエリファイルソースから出力を取得
- 29. ライブラリgoogle PageRank Checkerの出力を取得
- 30. 出力を取得できません
実際の最適化コードを表示するには、[here](https://stackoverflow.com/a/4678883/238419)の手順に従う必要があることに注意してください –