Jump to content
Xtreme .Net Talk

Recommended Posts

Posted
Find and read the ECMA IL spec, its not exactly engaging reading in places but you'll need to know exactly what you're doing and it tells you. After that have fun doing stuff like throwing strings straight past catch blocks and using fault and filter blocks.
Posted
ShaprDevelop seems to have the ability to do IL console apps but I have not tried it out other than noticing that it has that ability. Plus, you can download the source code -- the whole thing is written in C#. You might be able to find some tricks that way too.
Posted
Okay, interesting, but what 'real-world' purpose would you have in writing a program in IL? Just curious why you wouldn't do C# or C++...not trying to question the reasoning - doing something for it's coolness factor always hold weight :)
  • Leaders
Posted

I don't plan on writing any apps in IL or anything like that. But a small DLL? Maybe.

 

Why would I wanna do a thing like that? To write highly optimized code. I know that the usual response to this is "Do you really think that you can hand optimize better than the VB/C#/C++ optimizing compiler and JIT?" And generally, the answer is no. There are some ways, however, that you are restricted with VB and C# (less so as far as C# is concerned). I program primarily in VB and there are lots of things I notice that I don't like. The fact that there is no way to directly access certain memory (like bitmap data) without using a hacked out workaround that is still not as optimized as I like, the fact that when I cast in VB the compiler likes to throw in unnecessary calls to Microsoft.VisualBasic, the fact that integer overflow checks are all or none in an entire project, etc. Being able to program in IL gives you much more control. I can write slightly irregular loops and still optimize out the bounds check on array access. Most of all, I can micro-optimize to my heart's content. Maybe I have OCD but I would like to have the ability to get a little closer to the CLR in the same manner that an assembly programmer wants to get closer to the hardware.

[sIGPIC]e[/sIGPIC]
Posted

Sounds like fun...enjoy your own personal maintenance nightmare come to life! :D

 

[smiley is meant to indicate joke -- this is not intended as a sarcastic post.]

  • Leaders
Posted
doing something for it's coolness factor always hold weight[/Quote]

The coolness factor also certainly weighs in. And at the moment, I can write a nearly functionless console application in IL. I could not find the ECMA IL specification. I tried to use System.Windows.Forms.MessageBox to make a "Windows application," but when I tried I kept getting a syntax error. I tried what appeared to be the correct syntax. Then I opened a VB program with .Net Reflector and checked the disassembled IL and the syntax matched my appearently incorrect syntax. This is pretty frustrating stuff.

[sIGPIC]e[/sIGPIC]
Posted

First things first, you start by writing your il:

 

.assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) .ver 1:0:5000:0 }
.assembly extern System.Windows.Forms { .publickeytoken = (B7 7A 5C 56 19 34 E0 89) .ver 1:0:5000:0 }

.assembly messageboxtest { .ver 1:0:0:0 }

.class public auto ansi beforefieldinit MessageBoxTest extends [mscorlib]System.Object
{
 .method public hidebysig static void Main(string[] args) cil managed
 {
.entrypoint		// mark this method as the entry point
ldstr	"message"	// second argument for function
ldstr	"title"		// first argument for function

// call will call the function. The types are all fully qualified
// in [assembly]full.namespace::function(arg,list) format so there 
// can never be any resolution ambiguity

call	valuetype [system.Windows.Forms]System.Windows.Forms.DialogResult 
		[system.Windows.Forms]System.Windows.Forms.MessageBox::Show(string,string)														
	 
pop		// the call stored a return value on the evaluation stack, remove it
ret		// return from the method
 } 
}

 

To compile it put the il in a text file called messageboxtest.il use the command "ilasm /exe messageboxtest.il" at the commandline once you've run the vcvars batch file to get the .net tools on path.

 

A few things are worthy of note. Each assembly referenced (a reference in a vb or c# project) gets a .assembly extern directive. This identifies the name of the assembly and that it is not part of this binary, it also identifies the version expected and the public key token.

 

the local .assembly directive tells you what the current assembly thinks it is called, in my case messageboxtest. This means that if i had another program reference this assembly later i'd import it as ".assembly extern messageboxtest" and refer to types contained here as [messageboxtest]MyType.

 

the .class directive is pretty obvious for the most part, you'll understand whole flag list later on but right now all you need to know is that its a class called MessageBoxTest and it extends System.Object, as everything does. The .method directive is a similar mix of obvious and thing you don't need to know yet.

 

the .entrypoint directive in Main defines this method as the entry point for the asembly. There must be none or exactly and only one method marked with this directive in an assembly for obvious reasons.

 

Onto the code, load the argument strings onto the stack using ldstr instructions and then call the MessageBox.Show function from System.Windows.Forms.dll using its fully qualified name and argument list. the arguments are listed as "string" because string is an intrinsic type, like int and nativeint it doesn't need any qualification. If the argument were a user constructed type you would fully qualify it as you do the return value and the function containing class.

 

Once called (and you've clicked Ok) the return argument from the function is removed from the stack with a pop instruction. It looks like don't actually need to do this since the process is about to exit but its good form to clean up after yourself and it is actually important here as you'll see.

 

Finally ret. Ret will return the top value from the evaluation stack, which at the moment is empty because we removed the return value from Show() call.

 

If we hadn't pop'ed that value off the stack then ret would return it to the caller evaluation stack. A compiler would check these things and call foul, probably with a helpful mismatched return types warning or something similar. In IL the assembler blindly assumes you know what you're doing and lets you do stupid things. So don't if you can possibly help it.

 

Even though ilasm (the il assembler) won't complain about the return confusion if you miss that pop instruction there is a utility that'll tell you about the problem, peverify. If you comment out that pop and compile the IL you get no warnings, then run peverify on it "peverify messageboxtest.exe" and you'll get something like:

 

D:\Programming\IL>peverify messageboxtest.EXE

Microsoft (R) .NET Framework PE Verifier  Version 1.1.4322.573
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

[iL]: Error: [d:\programming\il\messageboxtest.exe : MessageBoxTest::Main] [offset 0
x0000000F] [opcode ret] Stack must be empty on return from a void function.
1 Errors Verifying messagebox.EXE

 

Thats very very handy indeed.

 

the best way i found to work out how to do something was to mock up a small (as small as possible) c# class that contains what i want to know, compile it with csc.exe and ensure that it works as i want and then use ildasm to get the il from it. From that point you can alter the il to change behavior and see how it works using ilasm and peverify. If it all goes wrong you can recompile and redump and il from the original exe.

 

tools needed: csc.exe, notepad.exe, ilasm.exe, ildasm.exe, peverify.exe, lots and lots of time and patience, opcode reference is essential.

 

Hope that helps :)

  • Leaders
Posted
Hmm... maybe I do have programmer's OCD. Either way... thanks Diesel, IngisKahn, and Wraith for the info. I'm having quite the difficult time finding much info on MSIL using google as a starting point. Didn't even know that there was info in my SDK. Who would have thought??
[sIGPIC]e[/sIGPIC]
Posted

I can think of one really good reason to know IL -

in 2.0 you can use the DynamicMethod class to generate functions

on the fly and attach them to assemblies - rates 10 on the coolness scale!

IN PARVUM MULTUM

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...