.NET Internals: Writing .NET IL/MSIL Code

Introduction

The .NET runtime uses IL (Intermediate Language) as a bridge language. It compiles all high-level .NET languages into this single language. This is why you can write multi-language applications in .NET. You can write part of your application in F#, while using a completely different .NET language for the rest. Behind the scenes, there's only one language: IL.

In our previous tutorial, we discussed the compilation process. Now, it's time to start writing simple applications using the .NET IL language.

Benefits of Learning .NET IL

Before we dive in, let's understand the value of learning .NET IL:

  1. Deeper Understanding: IL can help you understand what happens "under the hood" when you run your .NET program. This can be useful for debugging tricky problems or optimizing performance.
  2. Specific Tasks: In some advanced scenarios, like generating code dynamically, understanding IL can be helpful.

Setting Up the Environment

There's no need to install any special applications! You can use a simple text editor like Notepad++ (although Notepad++ is recommended). Visual Studio doesn't have a built-in template for writing IL code.

Open your preferred text editor and start development.

.assembly extern mscorlib {}
.assembly firstILProject {}
.module firstILProject.exe

.class public Program extends [mscorlib]System.Object
{
 .method public static void MyMain(string[] args) cil managed 
  {
	.entrypoint
	ldstr "Hello from IL code"
	call void [mscorlib]System.Console::WriteLine(string)
	call string [mscorlib]System.Console::ReadLine()
	pop
	ret
  }

}

Compiling Your Application

To compile your application, simply save it with a .il extension in any folder. Then, open the "developer command prompt" and run ilasm to compile your application.

Developer command prompt for Visual Studio

Sample Code Structure

Here's a breakdown of a typical IL code structure:

External Reference

.assembly extern mscorlib {}

This line references the external mscorlib library, which provides functionalities your application might need.

Main Assembly

.assembly firstILProject {}

This line defines your application assembly and gives it a unique name (firstILProject in this case).

Module Definition

.module firstILProject.exe

This line defines a module named "firstILProject.exe." A module can represent an executable file (.exe) or a Dynamic-link library (DLL).

Class Definition

.class public extends [System.Object] firstILProject

This line creates a public class named firstILProject that inherits from System.Object (all classes in .NET inherit from System.Object by default).

Entry Point Method

.method static public void Main()

This line declares the Main method, the entry point for your console application.

Stack Operations

method static public void Main()

    .entrypoint

    ldstr "Hello, World!"  // Load string "Hello, World!" onto the stack
    call void [mscorlib]System.Console::WriteLine(string)  // Call the WriteLine method to print the string

    pop                     // Remove the string from the stack
    ret                      // Return from the method
  • ldstr: This operator loads a string onto the stack.
  • call: This keyword is used to call existing methods.
  • pop: This removes the top element from the stack.
  • ret: This returns from the current method.

Conclusion

This is a basic overview of writing .NET IL code. By understanding these concepts, you can begin creating simple applications and delve deeper into the world of .NET internals.

Please don’t forget to like this article if you have found it useful, and also, please do not forget to follow me on my LinkedIn: https://www.linkedin.com/in/ tural-suleymani/. Happy learning!