This is a small experiment of little value, for everyone to understand. NET programming is almost no good, although Lao Zhao has always emphasized "foundation", such as solid algorithms and data structure capabilities, and some necessary support, such as operating systems, computer architecture, computer networks have enough knowledge, have "common sense", when necessary to have enough ability to understand But there are still some subjects, such as "compiler principle", which can enhance the understanding of a person's program, but I do not feel that this is a "road." It's certainly good to know the inside of a black box, but whether it is worthwhile to learn and weigh, at least consider (1) to understand how much of the benefits to a person, whether it is really so critical, (2) The same understanding of this knowledge, need to understand how deep, whether we walk is to understand these "only way". In the same way, Lao Zhao retains 1of his reservations about the practice of "IL" and "the bottom of the system" for that kind of problem. Of course, for hands-on experimentation and exploration, I always support it, which shows a rigorous academic attitude--but only if we're not "proud" to do this (Lao Zhao has also been stressing that the technical content of the application layer is worse than the so-called "bottom"), There is already a necessary foundation for this. We study for the sake of exploration, not for research.
Sometimes we need to see how the assembly instructions for a managed method are. Remember when we were in college, we used Gcc-s and objdump to get an assembler instruction for a C program code. But for. NET programs, it's certainly not easy for us to get these things. Because all the. NET programs are compiled into IL code, and are JIT-compiled only at run time. So, we have to go after the program is run, and then use some way to "probe" the assembly instructions why-unless we can let the JIT do not run the program to compile the IL code, Lao Zhao did not know how to do, may need a friend to point.
To do this experiment, let's write some simple sample code:
namespace TestAsm
{
public static class TestClass
{
public static int TestMethod(int i)
{
return i;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Before JIT.");
Console.ReadLine();
TestClass.TestMethod(1);
Console.WriteLine("After JIT");
Console.ReadLine();
TestClass.TestMethod(1);
}
}
}
You can create a new Testasm project, copy and paste the above code, and compile with debug mode (avoid TestMethod method being inline, which will cause TestMethod to never be JIT) 2, We can get a TestAsm.exe, that's our test objective. You can see that the code calls two times Testclass.testmethod methods and use Console.ReadLine interrupts before the call, which gives us an opportunity to explore using WinDbg. Let's do some preparatory work:
Run TestAsm.exe and see the Before JIT (preferably not run in VS, as this will add to the VS Debug Module-although this does not affect the test).
Open WinDbg (assuming you have set up symbol Path), press F6 (or File-attach to a Process), select TestAsm.exe and OK.
Load SOS (for example,. Load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 \sos.dll).
Now we are ready to do it. So what is our first step? Naturally, to find the "location" of the Testclass.testmethod method, you first use the!NAME2EE command to obtain information about the TestClass class:
0:003> !name2ee *!TestAsm.TestClass
Module: 70ca1000 (mscorlib.dll)
--------------------------------------
Module: 00942c5c (TestAsm.exe)
Token: 0x02000002
MethodTable: 0094306c
EEClass: 0094133c
Name: TestAsm.TestClass
"!name2ee *!" The meaning of the Testasm.testclass command is "to traverse all loaded modules and find the Testasm.testclass type". You can also use the "!name2ee ModuleName TypeName" method to find the specified type in the specified module, if needed. From the output we can see that the MethodTable address is 0028306c. So we use the!DUMPMT-MD <address> command to view the method descriptor for the TestClass type (methods descriptor):
0:003> !dumpmt -md 0094306c
EEClass: 0094133c
Module: 00942c5c
Name: TestAsm.TestClass
mdToken: 02000002 (C:\...\TestAsm\bin\Debug\TestAsm.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 5
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
70e66a70 70ce4934 PreJIT System.Object.ToString()
70e66a90 70ce493c PreJIT System.Object.Equals (System.Object)
70e66b00 70ce496c PreJIT System.Object.GetHashCode()
70ed72f0 70ce4990 PreJIT System.Object.Finalize()
0094c040 00943060 NONE TestAsm.TestClass.TestMethod(Int32)
And look at the status of the TestMethod JIT bar: "NONE", which means that this method has not been JIT compiled, if we at this time through the!u <address> command to view the assembly instructions of the method will see:
0:003> !u 0094c040
Unmanaged code
0094c040 e8755d9571 call mscorwks!PrecodeFixupThunk (722a1dba)
0094c045 5e pop esi
0094c046 0000 add byte ptr [eax],al
0094c048 60 pushad
0094c049 30940000000000 xor byte ptr [eax+eax],dl
0094c050 0000 add byte ptr [eax],al
0094c052 0000 add byte ptr [eax],al
0094c054 0000 add byte ptr [eax],al
0094c056 0000 add byte ptr [eax],al
0094c058 0000 add byte ptr [eax],al