Browse DevX
Sign up for e-mail newsletters from DevX


Down to the Metal: Managed Code Under the Hood (Part II) : Page 4

In this part of the series, you'll dig deeper into MSIL and learn to write conditional code, loops, and how to handle errors.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Exception Handling
To err is human. And therefore you will need structured exception handling if you want to write secure code. Always check the input values before you start processing them. That will keep you out of a lot of trouble.

As always let's start off with the sample code. We'll enhance the sphere example a little to make it a respectable citizen of your computer. The calculation method remains unchanged. Here's the part that changed:

.method static void main() cil managed { .entrypoint .maxstack 2 .locals init (float64) TryAgain: ldstr "Radius: " call void [mscorlib]System.Console::Write(string) .try { call string [mscorlib]System.Console::ReadLine() call float64 [mscorlib]System.Double::Parse(string) stloc.0 leave.s NothingBadHappend } catch [mscorlib] System.Exception { pop ldstr "Incorrect format. Try again, please." call void [mscorlib]System.Console::WriteLine(string) leave.s TryAgain } NothingBadHappend: ldloc.0 call float64 CalcSphereVolume(float64) ldstr "Volume: " call void [mscorlib]System.Console::Write(string) call void [mscorlib]System.Console::WriteLine(float64) ret }

You've already seen a good deal of the preceding code in the first sample, so I'll concentrate on what's changed—the error-handling code.

Local Variables
When using guarded blocks (code blocks that do take care of exceptions) you always need to leave the block with an empty evaluation stack. Because you'll need the value calculated in the guarded block later on, you have to store it to a local variable to get it off the evaluation stack.

To declare a local variable use the .locals init statement and include all local variables in a comma-separated list within parentheses. Remember that CLI defines a separate memory space for local variables and you need to declare all of them at the beginning of the method. In contrast, most high-level languages let you define variables wherever you like within the method body. Another difference is that in ILAsm you don't need to use variable names as you do in high-level languages; instead, ILAsm addresses variables by their index. You can use variable names, but the compiler will translate those names to indexes anyway.

The sample above declares one float64 variable to store the radius for the calculation.

To access this variable you use two methods: stloc stores the topmost item from the evaluation stack to a variable and ldloc pushes a variable's value on the stack. The code sample uses the short versions (ldloc.0 and stloc.0) to access the first (and only) local variable.

Guarded Blocks
To begin a guarded block use the .try directive (just as in C# or VB.NET) and delineate the block with curly brackets ({}). Although those brackets mark the beginning and end of the guarded block clearly you have to use a special opcode to actually leave the guarded block, the directive leave (or the short version leave.s). The leave directive causes execution to leave the guarded block without throwing an exception and to continue at a label position when no error occurred.

If an error occurs, code evaluation continues at the line containing the catch statement. The catch statement must specify what kind of exception it should catch, which is known as exception filtering. This simple example catches every exception of any kind, which you can do by using System.Exception, the base class of all exceptions as the caught exception type.

You haven't learned to use class instances, so for now, one way to handle an error is to simply pop the exception object off the evaluation stack and write a message to the user that something bad happened. Alternatively, you can jump back to a point in the code that forces the user to retry another input until the code finally completes without throwing an exception.

To sum up, so far you've seen the basics of functional programming with ILAsm. The list of opcodes shown here is not even close to complete, but a detailed explanation of ILAsm programming is beyond the scope of one article. If you are interested in more detail, take a look at the related resources column of this article. You can download the sample code here.

Additional Resources
See these two files in the Tool Developers Guide subdirectory of your SDK Installation.
  • Partition I Architecture.doc
  • Partition III CIL.doc

Peter Koen, a Microsoft MVP, is an independent consultant, author, and programmer. He also gives lectures at a private university in Austria on Knowledge Management. He is a certified MCP, MCAD, MCSD.NET, MCDBA, and MCT, as well as the Allied Telesyn Certifications for CAI, CASE, and IAT. Peter is the founder of the the SQL Server User group in Austria.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date