I'm interested in viewing the actual x86 assembly output by a C# program (not the CLR bytecode instructions). Is there a good way to do this?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Generic Generics in Managed C++
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
You could use Visual Studio Debugger by placing a breakpoint and then viewing the Dissassembly window (Alt+Ctrl+D) or try the Native Image Generator Tool (ngen.exe).
You can do a memory dump. However, note that the in-memory code does not necessarily contain every method.
ngen does AOT, or Ahead-of-time code generation, which can be different from JIT code.
While debugging your application in Visual Studio, you can right-click on a code where you have stopped (using breakpoint) and click "Go to Disassembly". You can debug through native instructions.
As for doing that with *.exe files on disk, maybe you could use NGen to generate native output and then disassemble it (although I never tried that, so I can't guarantee that it will work).
Here are some sample opcodes from simple arithmetic operation that was written in c#:
You should use WinDbg with SOS/SOSEX, ensure that method you want to see x86 code for is JITted in method tables and then see actual unassembly with
u
command. Thus you would see actual code.As others mentioned here, with ngen you could see code that is not exactly matches actual JIT compilation result. With Visual Studio it is also possible because JIT's compilation depends heavily on the fact if debugger is present or not.
UPD: Some clarification. WinDbg is a debugger also, but it is native one.
Here you can read about the technique in detail.
As @IvanDanilov answered, you can use WinDbg and SOS. I am answering separately to provide a walk-through.
In this example, I want to view the disassembly of the AreEqual() method from:
Steps:
C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release\TestArrayCompare.exe
).Add the directory containing the PDB file to the symbol path. For example:
In WinDbg's Command window, set a breakpoint when
clr.dll
is loaded via:Continue by running the 'Go' command:
g
clr.dll
ModLoad, load SOS:.loadby sos clr
Run BPMD to break on the method for which you wish to see the disassembly. For example:
Continue again by running the 'Go' command:
g
Run Name2EE to see the method descriptor. For example:
Run the BPMD command in the "Not JITTED yet" line. For example:
Continue again:
g
You should see "JITTED ..." in the Command window. Re-run the Name2EE command to see the address of the JIT code. For example:
Use the
u
command to disassemble, starting at the listed code address. For example:(For the above, I was using WinDbg 6.3.9600.17200 X86 from the Windows 8.1 SDK.)
One handy reference is the SOS.dll (SOS Debugging Extension) reference page on MSDN.