Contact NET also has about 1 years of time, net's internal realization has made a great attraction to me. Personally feel: to these bottom of the realization of understanding and skilled, to write their own code is a great help, well, nonsense not to say, please look at the bottom:
Both the. NET CLR and the Java VM are stacked virtual machines (stack-based VMs), which means that their instruction set (instruction set) is used in a stacked operation: The data at execution time is placed on the stack before the operation. JAVAVM has about 200 instructions (instruction), each instruction is 1 byte opcode (opcode), followed by an unequal number of parameters; the. NET CLR has over 220 directives, but some commands use the same opcode, so the number of opcode Slightly less than the number of instructions. Specifically, the opcode length of. NET is not fixed, most of the opcode length is 1 byte, and a small portion is 2 byte.
The following is a simple C # source code:
Copy Code code as follows:
Using System;
public class Test {
public static void Main (string[] args) {
int i=1;
int j=2;
int k=3;
int answer = I+J+K;
Console.WriteLine ("i+j+k=" +answer);
}
}
After compiling this source code, you can get an EXE program. We can go through ILDASM. EXE (figure 0) to reverse-compile the exe to observe the IL. I set the Il decompile column of Main () as follows, there are 18 il directives, some directives (such as ldstr and box) need to be followed by parameters, and some directives (such as ldc.i4.1 and add) do not need to be followed by parameters.
Figure-0
ldc.i4.1
stloc.0
ldc.i4.2
Stloc.1
ldc.i4.3
Stloc.2
ldloc.0
Ldloc.1
Add
Ldloc.2
Add
Stloc.3
ldstr "i+j+k="
Ldloc.3
box [Mscorlib]system.int32
Call string [Mscorlib]system.string::concat (object, Object)
call void [Mscorlib]system.console::writeline (String)
Ret
When this program is executed, there are three key memory types:
1. Managed Heap: This is a dynamically configurable (dynamic allocation) memory, which is managed by Garbage Collector (GC) during execution, and a Managed Heap is shared throughout the process.
2. Call stack: This is a memory that the. NET CLR manages automatically at execution time, and each Thread has its own call stack. Each call to method causes an extra record frame on the call Stack, and the record frame is discarded after it is completed. In general, the record Frame records the method parameter (Parameter), the return address, and the regional variable (local Variable). Both the Java VM and the. NET CLR are using 0, 1, 2 ... Numbering methods to distinguish variables.
3, evaluation stack: This is the memory that the. NET CLR manages automatically during execution, and each Thread has its own evaluation stack. The so-called stacked virtual machine refers to this stack.
There is a series of schematic diagrams that are used to explain the changes in the three types of memory during execution. First, after entering Main (), before any instructions have been executed, the memory status is shown in Figure 1:
Figure 1
Then execute the first instruction ldc.i4.1. This directive means: place a constant of 4 byte in the evaluation Stack, with a value of 1. After executing this instruction, the memory changes as shown in Figure 2:
ldc.i4.1: Represents loading a value of 1 into the stack, the syntax structure of the instruction is:
The LDC.TYPEVALUE:LDC instruction loads a constant of the specified type into the stack.
LDC.I4.NUMBER:LDC instructions are more efficient. It transmits an integer value of 1 and 0 to 8 to the evaluation stack
Figure 2
Then execute the second instruction stloc.0. This directive means to remove a value from the evaluation Stack and place it in the No. 0 variable (V0). The number No. 0 variable here is actually the I in the original code. After executing this instruction, the memory changes as shown in Figure 3:
Figure 3
The third and fifth instructions are identical to the first instruction, and the fourth and sixth instructions are identical to the second instruction. For the sake of saving space, I do not 贅 this one by one. To remind you that the 1th variable (V1) is in fact the original code in the J, and the 2nd variable (V2) is in fact the source of K. Figure 4~7 is the memory change diagram after the third to sixth instruction is executed:
Figure 4
Figure 5
Figure 6
Figure 7
Then execute the seventh instruction ldloc.0 and eighth instruction Ldloc.1: separate the values of V0 (i.e. i) and V1 (that is, j) into evaluation Stack, which is the preparation action before adding. Figure 8 and Figure 9 are the changes in memory after the seventh and eighth instructions have been executed:
Figure 8
Figure 9
Then execute the nineth instruction Add. The meaning of this directive is to take two values (i.e. I and j) from the evaluation stack and add the results back to the evaluation stack. After executing this instruction, the memory changes as shown in Figure 10:
Figure 10
Then execute the tenth instruction Ldloc.2. This instruction means: separate the value of V2 (that is, K) into the evaluation Stack, which is the preparation action before adding. After executing this instruction, the memory changes as shown in Figure 11:
Figure 11
Then execute the 11th instruction Add. Remove the two values from the evaluation stack and add the results back to the evaluation stack, which is the i+j+k value. After executing this instruction, the memory changes as shown in Figure 12:
Figure 12
Then execute the 12th instruction Stloc.3. Remove a value from the evaluation Stack and place it in the 3rd variable (V3). The number 3rd variable here is actually the answer in the original code. After executing this instruction, the memory changes as shown in Figure 13:
Figure 13
Then execute the 13th instruction ldstr "i+j+k=". The meaning of this instruction is to put "i+j+k=" Reference into evaluation Stack. After executing this instruction, the memory changes as shown in Figure 14:
Figure 14
Then execute the 14th instruction Ldloc.3. Put the V3 value into the evaluation Stack. After executing this instruction, the memory changes as shown in Figure 15:
Figure 15
Then to execute the 15th instruction box [Mscorlib]system.int32, From here, you can see thatint to string is actually boxing operations, so there will be performance loss, can be reduced in the future coding of boxing operations to improve performance . This directive means to remove a value from the evaluation Stack and make this value type package (box) the Reference type. After executing this instruction, the memory changes as shown in Figure 16:
Figure 16
Then execute the 16th instruction call string [mscorlib] System.string::concat (object, Object). The meaning of this directive is to take two values from the evaluation Stack, which are Reference Type, the following value as the first argument, and the value above as the second argument, to call the mscorlib.dll provided System.String.Concat () method to move the two parameters into string join (string concatenation), put the new string of joints in Managed Heap, and Reference them into evaluation Stack. It is noteworthy that since System.String.Concat () is static method, the instruction used here is call rather than callvirt (calling virtual). After executing this instruction, the memory changes as shown in Figure 17:
Figure 17
note that the Int32 (6) and String ("i+j+k=") in the Managed Heap are no longer involved, so they become garbage and wait for the GC to be recycled.
Then execute the 17th instruction call void [mscorlib] System.console::writeline (String). This directive means to remove a value from the evaluation Stack, which is the Reference Type, which takes this value as a parameter and calls the System.Console.WriteLine () method provided by mscorlib.dll. To display this string on the Console window. System.Console.WriteLine () is also static method. After executing this instruction, the memory changes as shown in Figure 18:
Figure
Then execute the 18th instruction ret. This instruction means: the end of this call (that is, the call to Main). This will check the rest of the evaluation stack, since Main () declares that no outgoing value (void) is required, so evaluation Stack has to be empty, and this example fits the situation, so this call can be Li this time. The program also ends with the call of Main. After executing this instruction (and before the program is finished), the memory changes as shown in Figure 19:
Map
With this example, the reader should have a basic understanding of IL. Readers interested in IL should read Serge Lidin's Inside Microsoft. NET IL Assembler (Microsoft Press publishes). I think that knowing the role of IL per instruction is a prerequisite for. NET programmers.. NET programmers can not write programs with Il Assembly, but at least understand the ILDASM-compiled IL combination code.