我有興趣查看C#程序(不是CLR字節碼指令)的實際x86彙編輸出。有沒有一個好的方法來做到這一點?檢索JIT輸出
檢索JIT輸出
回答
您應該在SOS/SOSEX中使用WinDbg,確保您希望查看x86代碼的方法在方法表中被打亂,然後使用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或提前生成代碼,它可以與JIT代碼不同。
由於@IvanDanilov answered,您可以使用WinDbg和SOS。我正在單獨回答,以提供一個步驟。
在本例中,我想從查看AreEqual()方法的拆卸:
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的。從文件菜單中,選擇「打開可執行文件...」。瀏覽到EXE的位置(在我的情況下,
C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release\TestArrayCompare.exe
)。 將包含PDB文件的目錄添加到符號路徑中。例如:
g
- 在
clr.dll
:sxe ld:clr
通過運行 '開始' 命令繼續:
.sympath "C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release"
在WinDbg中的命令窗口中,當
clr.dll
通過加載設置斷點ModLoad,加載SOS:.loadby sos clr
運行BPMD以斷開您無線的方法噓看到拆卸。例如:
0:000> !BPMD TestArrayCompare.exe TestArrayCompare.Program.AreEqual Adding pending breakpoints...
通過運行 '開始' 命令,再繼續:
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.
在「Not JITTED yet」行中運行BPMD命令。例如:
0:000> !bpmd -md 00a637a4 MethodDesc = 00a637a4 Adding pending breakpoints...
再繼續:
g
您應該看到 「實時編譯......」 在命令窗口中。重新運行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 ...
(針對上述情況,我使用的WinDbg 6.3.9600.17200 X86從Windows 8.1 SDK。)
一個簡便的參考是SOS.dll (SOS Debugging Extension) reference page on MSDN。
- 1. PHP從MySQL檢索輸出
- 2. Drools - 檢索輸出對象
- 3. 檢索輸入,顯示隨機輸出
- 4. 檢索python輸出爲c#輸入
- 5. 檢索exec()輸出時出錯
- 6. 檢索bash的輸出歷史
- 7. SQL查詢以檢索輸出
- 8. 從django'manage.py sql appname'檢索mysql輸出
- 9. 如何從json輸出中檢索值?
- 10. 如何從json輸出檢索數據
- 11. 檢索R中的循環輸出
- 12. 檢索和輸出行從數據庫
- 13. 使用wininet.dll檢索FTP命令輸出
- 14. 從駱駝上下文檢索輸出
- 15. XMLHttpRequest:從Web服務檢索輸出
- 16. 檢索標準輸出變量
- 17. 使用bash/node檢索命令輸出
- 18. 檢索XML輸出從SQL Server 2005
- 19. 使用perf_events/oprofile分析Linux上JIT的輸出?
- 20. SQL Server 2008 R2 - 檢索程序輸入/輸出參數
- 21. 在MonoTouch中編譯時檢測JIT
- 22. 如何從dot net webservices檢索給出json輸出的值?
- 23. STRCPY索引輸出
- 24. Asp.net + JIT?
- 25. 檢查在輸出
- 26. 檢查輸出空
- 27. 檢索輸入文本值
- 28. 根據輸入檢索行
- 29. 檢索在輸入字段
- 30. JavaScript表單輸入檢索
請注意,如果您想查看實際優化代碼,則需要按照[此處](此處)(https://stackoverflow.com/a/4678883/238419)中的步驟操作 –