Emit Learning (2), emit Learning
Learning Emit is essential to use the IL intermediate code. when I first saw the IL code, I had a feeling of assembly. It reminds me of learning 8051 assembly language in college. if there are too many commands, you can directly go to the question. Is there a daunting sense of OpCodes Instruction Set? There are so many instructions I have never counted, but it must be a lot more than 8051 of instructions, there should be more than 200, but in the actual use process, it is certainly not used so much, so it is enough to grasp some common, the rest, you can check the information. (This was also the case for university teachers. In actual use, it was indeed the case)
I. Example
At the end of the previous article, I posted an OpCodes file for the Chinese comments version. This part of content is closely related to that file. It seems that it is more appropriate to paste it in this article...
Well, we should start from the example.
Source: http://www.cnblogs.com/zery/p/3366175.html
Static void Sum (int sum, string sumStr) {int a, B, c; a = 1; B = 2; c = 3; sum = a + B + c; sumStr = sum. toString (); Console. writeLine (sumStr); for (int I = 0; I <c; I ++) {if (I> B) {Console. writeLine ("meet the conditions, jump out of the loop"); break ;}} Console. readKey ();}
. Method private hidebysig static void Sum (int32 sum, string sumStr) cel managed {. maxstack 2 // defines the maximum depth of the stack used by function code. It also means that the Evaluation Stackk can have two values at the same time. locals init (// variable Declaration, (num, num2, num3, num4, and flag have been stored in the Record Frame of the Call Stack) [0] int32 num, [1] int32 num2, [2] int32 num3, [3] int32 num4, [4] bool flag) L_0000: nop // No operation, you can ignore L_0001: ldc. i4.1 // load constant 1 to the stack (pressure stack) L_0002: stloc.0 // extract constant 1 from the stack and assign it to num (Out of stack, there is nothing in the stack.) L_0003: ldc. i4.2 // load constant 2 to stack (pressure stack) L_0004: stloc.1 L_0005: ldc. i4.3 L_0006: stloc.2 L_0007: ldloc.0 // press the num variable to stack L_0008: ldloc.1 // press the variable num2 onto the stack (there are two values in the stack, num2 on the top, and num on the bottom) l_0009: add // press the result of sum of num and num2 to the stack (when sum is used, both values are extracted, so after the end, there is only one result value in the stack) L_000a: ldloc.2 // press the num3 stack L_000b: add // sum the num3, (num + num2), and press the stack. At this time, only the final result value Rochelle 000c: starg is in the stack. s sum // pass the value at the top of the stack to the parameter sum (short format) L_000e: ldarga. s sum // load the sum Address on the stack (short format) L_0010: call instance string [mscorlib] System. int32: ToString () // call ToString () to complete format conversion. Put the result value into the stack L_0015: starg. s sumStr // pass the value at the top of the stack to the passing parameter sumStr (short format) L_0017: ldarg.1 // load the passing parameter (sumStr) with an index of 1 into the stack L_0018: call void [mscorlib] System. console: WriteLine (string) // call Console. writeLine method L_001d: nop L_001e: ldc. i4.0 L_001f: stloc.3 // I = 0 L_0020: br. s L_0043 // jump to the following unconditionally to determine whether I <c is true L_0022: nop L_00 23: ldloc.3 // I L_0024: ldloc.1 // B L_0025: cgt/I> B? 1: 0 L_0027: ldc. i4.0 // The pressure stack 0 L_0028: ceq // comparison result is compared with 0, (I> B? 1: 0) = 0? 1: 0 L_002a: stloc. s flag // Save the result to the local variable flag L_002c: ldloc. s flag // load the flag to the stack L_002e: brtrue. s L_003e // jump to L_003e L_0030: nop L_0031: ldstr "\ u6ee1 \ u8db3 \ u6761 \ u4ef6, \ u8df3 \ u51fa \ u5faa \ u73af" // "to meet the conditions, jump out of the loop "L_0036: call void [mscorlib] System. console: WriteLine (string) L_003b: nop L_003c: br. s L_004d L_003e: nop L_003f: ldloc.3 // I L_0040: ldc. i4.1 // 1 L_0041: add // I + 1 L_0042: stloc.3 // I = I + 1 L_0043: ldloc.3 // I L_0044: ldloc.2 // c L_0045: clt // I <c? 1: 0 L_0047: stloc. s flag // pass the result to flag L_0049: ldloc. s flag // load the flag variable to the stack L_004b: brtrue. s L_0022 // true jump L_0022 L_004d: call valuetype [mscorlib] System. consoleKeyInfo [mscorlib] System. console: ReadKey () L_0052: pop // remove the current value at the top of the computing stack L_0053: ret // that is, return flag return value}
Ldc. i4.1: i4 -- int32, 1 -- value. Together, the int32 value 1 is loaded into the stack.
Stloc.0: 0 -- the first one in the previously declared locals variable group will pay the value at the top of the stack to the locals0 variable.
Ldloc.0: load the locals0 variable to the stack.
Add: sum the two values at the top of the stack and press the result on the stack.
2. Common commands
Source: http://blog.csdn.net/joyhen/article/details/47276433
1. Common loading commands
Ldarg (and multiple variations) |
Ld -- load, arg -- argument. No stranger to anyone. Load the parameter value of the method to the stack. In addition to the generic ldarg (which requires an index as a parameter), there are many other forms of change later. '.' Has a numeric suffix ldarg operation code to specify the parameters to be loaded. A -- address, s -- short Ldarga/ldarga. s indicates the address of the loaded parameter, rather than the value of the loaded parameter. |
Ldc (and multiple variations) |
C -- constant, the const keyword must be familiar to everyone. constant indicates a constant. Load a constant into the stack Ldc. I4.2 i4 indicates the int32 value (1 indicates 8 bits), and 2 indicates a constant. |
Ldfld (and multiple variations) |
Attach members of an object instance to the stack |
Ldloc (and multiple variations) |
Loc -- locals Load a local variable to the stack |
Ldobj |
Obtain all the data of a heap object and place them in the stack. OpCodes: copy the value type object pointed to by the address to the top of the computing stack. |
Ldstr |
Load a string of data to the stack |
2. Frequently used pop-up operation commands
Pop |
Deletes the value at the top of the current stack, but does not affect the stored value. |
Starg |
St -- store Store the value at the top of the stack to the parameter of the given method. Determine this parameter based on the index. OpCodes: store the value at the top of the computing stack to the parameter slot in the specified index. |
Stloc (and multiple variations) |
The value at the top of the current stack is displayed and stored in a local variable list. |
Stobj |
Copy a specific type from the stack to the specified memory address |
Stfld |
Replace the value of an object member with the value obtained from the stack. |
3. Other commonly used operation commands
Add, sub, mul, div, rem |
It is used to calculate the modulus of addition, subtraction, multiplication, division, and push the result to the computing stack. |
And, or, not, xor |
Binary operation on two values |
Ceq, cgt, clt |
Compare two stack values using different methods C -- compare Ceq: Equal? -- if the two values are equal, the integer 1 (int32) is pushed to the computing stack; otherwise, 0 (int32) is pushed to the computing stack. Cgt: whether it is greater than -- if the first value is greater than the second value, the integer 1 (int32) is pushed to the computing stack; otherwise, 0 (int32) is pushed) push to the computing stack. Cgt. un -- compare two unsigned or unsortable values, un -- unsigned Clt: whether it is smaller than -- if the first value is smaller than the second value, the integer 1 (int32) is pushed to the computing stack; otherwise, 0 (int32) is pushed) push to the computing stack. |
Box, unbox |
Convert Between Reference Type and Value Type Box: Packing Unbox: unbox |
Ret |
Exit method and return a value |
Beq, bgt, bge, ble, blt, switch |
Condition branch in Control Method B -- break, eq, e -- equal Beq: if the two values are equal, the control is transferred to the target command; Bgt: if the first value> the second value, the control is transferred to the target command. Bge: if the first value> = the second value, the control is transferred to the target command. Ble: if the first value is <= the second value, the control is transferred to the target command. Blt: if the first value is <The second value, the control is transferred to the target command. Switch: Jump table For all branch control operation codes, you need to provide a template code label as the condition to jump to the destination. |
Brtrue |
If the value is true, non-null, or non-zero, the control is transferred to the target command. |
Br/br. s |
Br :( unconditional) Abort to code tag Br. s: transfer control unconditionally to the target command (short format) |
Call |
Call a member |
Newarr, newobj |
Create a new array or object type in memory Newarr: pushes the reference of the new one-dimensional array from scratch (its elements belong to a specific type) to the computing stack. Newobj: Creates a new object or instance of the value type, and pushes the object reference (O type) to the computing stack. |
To be continued ......