How can I view MSIL / CIL generated by C# compiler? Why is it called assembly?
- Yes it is, more exactly in the
.text
section of the PE file (portable executable = *.exe or *.dll). More information can be found here. - 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.
- 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:
opcode | instruction | description |
---|---|---|
0x02 | ldarg.0 | Load argument 0 onto the stack. |
0x03 | ldarg.1 | Load argument 1 onto the stack. |
0x58 | add | Add two values, returning a new value. |
0x0A | stloc.0 | Pop 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
How to Export a Jqgrid Data to Excel Using C#
Static Generic Class as Dictionary
An Attempt Was Made to Access a Socket in a Way Forbidden by Its Access Permissions
How to Find the Difference Between Two Images
Is Inaccessible Due to Its Protection Level
Displaying Arabic Characters in C# Console Application
Double Buffering When Not Drawing in Onpaint(): Why Doesn't It Work
Why Can't I Use System.Io.File Methods in an MVC Controller
Wpf: How to Override Part of a Controltemplate Without Redefining the Whole Style
How to Restrict/Control the Navigation Routes the User Can Visit Based on Login Status/Role
Outofmemoryexception While Populating Memorystream: 256Mb Allocation on 16Gb System
Zoom and Translate an Image from the Mouse Location
C# "Internal" Access Modifier When Doing Unit Testing