Emit Learning (2), emit Learning
I went home last weekend to enjoy my life and work for a better life. So I made a comparison between my life and work. these days are not very busy. When I learn my work skills and post a blog post, I can take a study note.
In the previous article, the elder brother in the posted address also has an article on Value Type and reference type.
Source: http://www.cnblogs.com/yingql/archive/2009/03/23/1420026.html
I am a little different from his. You can look at it, please!
I. Example
public class Person { public string Name { get; set; } public int Age { get; set; } } class Program { private Random rand = new Random(DateTime.Now.Millisecond); private Person person = new Person { Name = "Elvin", Age = 26 }; private string pro = "pro"; private double dou = 3.14; static void Main(string[] args) { Console.WriteLine("Main"); Console.ReadKey(); } }
Decompile the constructor of Program. The Code is as follows:
Public Program () {this. rand = new Random (DateTime. now. millisecond); Person person = new Person {Name = "Elvin", Age = 0x1a}; this. person = person; this. pro = "pro"; this. dou = 3.14 ;}. method public hidebysig specialname rtspecialname instance void. ctor () cel managed {. maxstack 3. locals init ([0] class ConsoleApplication3.Person person, [1] valuetype [mscorlib] System. dateTime time) L_0000: ldarg.0 // load this, which is an address that sink this into the background for a moment. rand = new Random () Service
L_0001: call valuetype [mscorlib] System. dateTime [mscorlib] System. dateTime: get_Now () L_0006: stloc.1 // initialization time, which is the current time L_0007: ldloca. s time // The address for loading time. Why is the address loaded? I will introduce it in detail later. let me sell a customs sub (1) L_0009: call instance int32 [mscorlib] System. dateTime: get_Millisecond () // call the Datetime method of the struct L_000e: newobj instance void [mscorlib] System. random ::. ctor (int32) // new Random (), put the object into the heap, and press the address stack L_0013: stfld class [mscorlib] System pointing to this object. random ConsoleApplication3.Program: rand // assign the obtained address to rand to implement this. rand = new Random () function Rochelle 0018: ldarg.0 // load this address and fill this into the background for a moment. person = person Service
L_0019: newobj instance void ConsoleApplication3.Person ::. ctor () // new Person () L_001e: stloc.0 // person = new Person (). The person here is not this. person. Note: L_001f: ldloc.0 // loads the person. Why is ldloc used here instead of ldloca? Answer: L_0020: ldstr "Elvin" // load "Elvin" string L_0025: callvirt instance void ConsoleApplication3.Person: set_Name (string) // person. name = "Elvin" L_002a: nop L_002b: ldloc.0 L_002c: ldc. i4.s 0x1a L_002e: callvirt instance void ConsoleApplication3.Person: set_Age (int32) L_0033: nop L_0034: ldloc.0 // load person, not this. person L_0035: stfld class ConsoleApplication3.Person ConsoleApplication3.Program :: Person // assign a value to this. person, this. person = person L_003a: ldarg.0 // load this. What is this loaded here? (2) L_003b: ldstr "pro" // load "pro" string L_0040: st1_string ConsoleApplication3.Program: pro // this. pro = "pro" L_0045: ldarg.0 L_0046: ldc. r8 3.14 L_004f: stfld float64 ConsoleApplication3.Program: dou L_0054: ldarg.0 L_0055: call instance void [mscorlib] System. object ::. ctor () L_005a: nop L_005b: ret}
We should be able to understand the example. The burden above will be revealed below.
Ii. Notes
Before revealing the answer, open a window.
We should all know how the value type and reference type are stored. If there are too many values, we will not explain them. Let's look at the previous figure.
2. stfld -- well, before, I still want
First, let's look at the working principle of stfld, that is, the stack conversion behavior is as follows:
In order:
1. Push an object reference or pointer to the stack
2. Press the value into the stack.
3. This value and the reference/pointer of the object are popped up from the stack. The object field is updated to the replaced value.
Detailed analysis: http://www.cnblogs.com/jackson0714/p/4995948.html
It can be seen from the above that it is necessary to pass the address, first pass the address, in the value, and then call the stfld command to complete the value assignment operation, so here a ldarg.0 is passed to complete this. pro = "pro" Function
1. ldloc and ldloca
From the above example, we can see that ldloc is used when Person is used, while DateTime is used, ldloca is used. Here we can see the difference between the reference type and the value type.
When calling a method, because the reference type is in the stack and the address is stored, you can directly call the internal method,
The value type does not directly store the address. Therefore, when calling the internal method, the address is actually transferred to implement this function.
Objects and struct (value types are essentially struct, such as int and decimal) are called by passing the address when calling their own methods, properties, and fields. time. year (), the time here is the address, person. name, the person here is also an address
This buddy has a more detailed introduction to IL: http://www.cnblogs.com/jackson0714/p/DotNET_IL3.html#_label4