How to View Msil/Cil Generated by C# Compiler? Why Is It Called Assembly

How can I view MSIL / CIL generated by C# compiler? Why is it called assembly?

  1. Yes it is, more exactly in the .text section of the PE file (portable executable = *.exe or *.dll). More information can be found here.
  2. The best choice is to use ILSpy (Reflector is no longer free). It's a free disassembler that can dissassemble your assembly into MSIL but also C#, VB (to some extent). The .NET Framework SDK contains ILDasm, which is the official MSIL dissasembler.
  3. Basically yes. An assembly is a file that contains MSIL code and corresponding metadata. This is not restricted to PE files per se, but all current CLR implementations use them.

If I may recommend a good book on that matter too, it's Expert .NET 2.0 IL Assembler by Serge Lidin. He's the guy who designed MSIL.

Which code is MSIL? Is the code generated by ILDASM MSIL?

MSIL is the "machine code like" language that the C# compiles your code
into.

The CLR is the "machine" that the MSIL runs on.

When runinng the MSIL the CLR converts your code into real machine code
using the JIT.

The real machine code is run on your computers actual CPU.

The MSIL Assembler (Ilasm.exe) generates a portable executable (PE) file from Microsoft intermediate language (MSIL). ILDASM is the disassembler to do the opposite.

The PE format is used for EXE, DLL, SYS (device driver), and other file types.

IL (MSIL) And Inside Of dll

You can actually test this yourself.
Create a new Library project, and a single function:

public class Class1 {
public static int Add(int a, int b) {
return a + b;
}
}

Compile into a DLL, and open the DLL in ILSpy. Navigate to your Add() function, and change the dropdown from C# to IL. You'll see something like this:

    IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: stloc.0

These are the human-readable representation of your IL. In ILSpy you can click on each of the instructions (e.g. ldarg.0) to see what they do, and their hexadecimal instruction code. Wikipedia has a full list of them.

So our Add() function in CIL would be the following:
































opcodeinstructiondescription
0x02ldarg.0Load argument 0 onto the stack.
0x03ldarg.1Load argument 1 onto the stack.
0x58addAdd two values, returning a new value.
0x0Astloc.0Pop a value from stack into local variable 0.

Confused about MSIL

You are right. .NET DLL's and EXE's (called assemblies in .NET) are the ones that contain MSIL. DLL's can have another format than the .NET ones, so that's why the .NET assemblies have a header that makes them recognizable as such. You can use corflags.exe to check if an DLL/EXE is a .NET DLL/EXE.

The IL code in the assembly is interpreted by the CLR (Common Language Runtime), which translates it to machine code. You can't see that step actually since it is done by the JIT'ter at runtime (or you should pre-compile the assemblies using ngen.exe and read the generated files).

How to access the MSIL code of compiled .NET assemblies?

Managed DLLs and EXEs are in MSIL.

You can see the MSIL using ildasm.exe.

Understanding .NET compilation

There is no assembly code in .net assemblies.

.Net programs are converted to a .NET Assembly, which is an .exe or .dll that contains intermediate bytecode. See CIL

Visual Studio will place the .NET Assemblies in your project's /bin or /bin/Release). You can change this path.

The dll or .exe are the assembled files which are generated inside the cited folders.

Both files can run on linux as long as the framework version is supported by the plataform.

Full .net framework is only for windows, but mono and core are being ported to linux.

https://learn.microsoft.com/en-us/dotnet/standard/assembly/

IL code vs IL assembly: is there a difference?

A .NET assembly does not contain MSIL, it contains metadata and bytes that represent IL opcodes. Pure binary data, not text. Any .NET decompiler, like ildasm.exe, knows how to convert the bytes back to text. It is pretty straight-forward.

The C# compiler directly generates the binary data, there is no intermediate text format. When you write your own IL code with a text editor then you need ilasm.exe to convert it to binary. It is pretty straight-forward.

The most difficult job of generating the binary data is the metadata btw. It is excessively micro-optimized to make it as small as possible, its structure is quite convoluted. No compiler generates the bytes directly, they'll use a pre-built component to get that job done. Notable is that Roslyn had to rewrite this from scratch, big job.

How to compile CIL code?

You can use the ilasm tool.

ilasm /exe Your.il /deb=opt
peverify /md /il Your.exe

ilasm compiles it, peverify verifies it.



Related Topics



Leave a reply



Submit