The secret inside CLI ... (1) Overall introduction, and CIL
I don't know what I have learned for Common language Infrastructure? "Oh! God! I will take a few English!" If this is true, then you have no way to continue to look, because this thing is basically able to find English information.
In fact, this seemingly deepest thing doesn't seem to be as difficult, of course, is not a simple thing. About this information is actually very easy to find, although there is not much, but it is very practical, just in the catalog of your VS installation. If you installed VS2003, put it in the e: /vs.net 2003 this directory, then the relevant information is in E: /VS.NET 2003 / SDK / V1.1 / Tool Developers Guide / inside. There are two subdirectory below this directory, one is DOCS, all of which are documents, and the other is Samples, all is examples, but all things are English.
What is a CLI? Chinese should be translated into "public language underlying structure". The CLI should include CIL and CLR: CIL is Common Intermediate Language, and Chinese is "public intermediate language", which is the "IL assembly"; CLR is Common language runtime, and Chinese is "Public Language Runture". In addition to these, any .NET language also received CLS constraints, CLS - Common Language Specification, public language specifications, this thing is mainly used to constrain all .NET language, making them able to cooperate with each other, there is no certain The code generated by the language cannot be supported by another language.
If you really have fun to see the documents in the directory I said, you will find that almost what you can think of, including CIL's grammar and binary code, CLI executable program file structure, how Write a debugger, analyzer (PROFILER), compiler ... what? Do you not believe that the compiler has? There are three compilers in E: /VS.NET 2003 / SDK / V1.1 / TOOL DEVELOPERS GUIDE / SAMPLES! A Lisp.Net, a Myc, a Simple Managed C. There are more examples, all the public.
Today, I will talk about CIL and CIL VM. About CIL documents, in Partition III CIL.DOC. If you don't want to see, I can talk simplely. CIL's VM is a stack machine, and the mechanism of the X86's dependent register is very different. The so-called stacking machine is that the data required by the instruction is saved with the stack. This stake machine is not very common in real computers, especially in Cisc's CPU, it is very difficult to see, even in RISC, it is rare (maybe I am alive). The reason is simple to say that the instruction of the stack machine is very simple. In order to perform a plurality of instructions, multiple instructions are required, and even read and write data multiple times. It is because the instruction is simple, so because the virtual machine is very convenient, virtual machine programs can be easier to do. The main instructions of the stack machine have five categories: (data) stack, pop-up, operation, transfer, other, where the top three are the core of the stack machine. Take CIL as an example:
INT A = A B C D E F G H I;
80x86 asmcil
0000004C 8B 54 24 10 MOV EDX, DWORD PTR [ESP 10h]
00000050 03 54 24 14 Add EDX, DWORD PTR [ESP 14H]
00000054 03 54 24 18 Add Edx, DWORD PTR [ESP 18H]
00000058 03 54 24 1C Add EDX, DWORD PTR [ESP 1CH]
0000005C 03 54 24 20 Add Edx, DWORD PTR [ESP 20H]
00000060 03 D5 Add EDX, EBP
00000062 03 D6 Add EDX, ESI
00000064 03 D3 Add EDX, EBX
00000066 03 D7 Add EDX, EDI
00000068 89 54 24 10 MOV DWORD PTR [ESP 10H], EDX
IL_0000: 06 ldloc.0 // a
IL_0001: 07 ldloc.1 // b
IL_0002: 08 ldloc.2 // c
IL_0003: 09 ldloc.3 // d
IL_0004: 11 04 ldloc.s e
IL_0006: 11 05 ldloc.s f
IL_0008: 11 06 LDLOC.S G
IL_000A: 11 07 ldloc.s h
IL_000c: 11 08 LDLOC.S I
IL_000e: 58 Add // Stack [TOP] = stack [top ---] stack [TOP ---] = stack [top] = H i;
IL_000F: 58 Add // Stack [TOP] = G H I
IL_0010: 58 add // = f g h i
IL_0011: 58 Add // = E F G H i
IL_0012: 58 Add // = D E F G H I
IL_0013: 58 Add // = C D E F G H I
IL_0014: 58 Add // = B C D E F G H i
IL_0015: 58 Add // = a b C D E F G H i
IL_0016: 0A STLOC.0 // a = ...
Table I
Let's take a look at the CIL on the right, and LDLOC means pressing local variables into the stack, followed .0 means a zero partial variable (that is, A); add the two elements of the stack to the top of the stack Add, the result is pressed onto the top; STLOC pops up the contents of the top of the stack and saves the local variable. It should now be seen that LD is the abbreviation of LOAD, ST is the abbreviation of the Store, LOC is LOCAL. So there is anything else? You can take a look at the table below:
Main Operation Operation Scope / Condition Operation Type Operation Number Repersion Full-name Meaning Abbreviation Full Nominal Meaning Abbreviation Full-name Meaning Abbreviation The full name meaning LDLOAD Operate the operating number to the stack, equivalent to: Push AxarGument parameter ?? Number of operands .0? Zero parameter * .1? First parameter. 2? Second parameter .3? The third parameter. Sx (short) parameter xxaaddress operand is only .s XX, see ldarg.sloclocal local variables See ldargfldfield Field (class global variable) See ldargxx? Xx field, eg: ldfld xxcconst constant .I4int 4 bytesc # inside INT, other types such as Short needs to convert through CONV. M1minus 1-1.0? 0.1? 1 ......8 8 .s (Short) Back to the integer value (with symbol) of one byte ?? Here with four bytes. I8int 8 Bytesc # inside the long behind the eight bytes Type value. R4REAL 4 BYTESC # inside FLOAT ?? Back with four bytes floating point value. R8REAL 8 BYTESC # inside Double ?? behind the backpoint of floating point numerical nullnull null value (ii0) ?????? StStore pops the stack content into the operands, equivalent to: POP AX See the ld ** convonvert value type conversion, only the transition between pure numerical types, such as Int / Float, etc. ???. I1Int 1 bytesc # inside Sbyte ???. I2int 2 bytesc # inside short.i4int 4 bytesc # inside INT.R4REAL 4 BYTESC # inside the float.r8real 8 bytesc # inside the float.r8real 8 Bytesc # inside DoubleSc # U4uint 4 bytesc # inside UINT.U8uint 8 Bytesc # inside Ulongb / Brbranch conditions and unconditional jumps, equivalent to: jmp / jxx label_jumpbr ?? unconditional jump ????? After the offset of four bytes (Symbol). S (SHORT) Behind the offset (with a symbol) falsefalse value is zero, see the BRTRUETRUE value is not zero, jump ??? beqequal to equally? ?? Nenot Equal TO is not equal in ununsigned or unordered fluorless (for integers) or disorderless (for floating point) Gtgreater Than is smaller than gegreater Than or equal to gregar than or equal to LELESS THAN OR Equal TO is less than or equal to CallCall call ???? (non-virtual function) ???? Virtvirtual virtual function * The leftmost parameter 0, then parameter 1, 2, 3 ... If not in static, the parameter 0 corresponds to the THIS (VB ME) of the C #, which does not require code delivery. At this time, the leftmost parameter is parameter 1, that is, from .1 start. ** STARG is only .s in form, no .0, .1, etc., in addition to this and LDARG. From left to right, you can get an instruction, such as: LD Arg A .S XX? =>? Ldarga.s xx, that is, read the address of the parameter XX and press.
These are just some commonly used, but a slightly difficult instructions, other documents that can see the Partition III CIL.DOC. Now let's go back to the example, is it to feel that the CIL is very good? Therefore, the form of virtual machine stacking machine is easier to implement, which can be simpler than the status / flag of a bunch of registers, status / flags, and instructions in X86! However, we can also see that 10 instructions can be done with 80x86 compilation, and 18 instructions are required to use CIL, and this is already manually optimized CIL, if you use C # write, then compile it is likely There are more code. If we include the number of bytes, you can see 80x86 has 32bytes, and CIL only 20bytes, may make you feel that CIL seems to be more compact, actually because this CIL is an optimized form, the actual situation CIL is not It will be small than X86 compilation, and it is even completely larger! A stack machine is another problem is that each operation must access at least two memory, and the two access is not the same place: one is a memory block, and the other is a stack. Therefore, it is impossible to directly access the CPU internal memory, and even access cache efficiency will be folded (need to access two completely unrelated places). And we know that the CPU internal memory is the fastest, completely free of delay, the cache is second (first-level caching delay is about 1 to 2 cycles, the secondary cache delay 3 to 5 cycles), the slowest is memory (Delayed about ten cycles or even longer). So, it is generally, the real CPU is rarely made in the form of a stake. So what skills do we have to read CIL? I think I need to pay attention to so:
Keep in mind this is a stake machine, all instructions are related to the stack. Note whether the current function is so much static function.
Note: Original article from http://dotnet.mblogger.cn/sumtec/posts/193.aspx