Free mag vol1 | Page 719

CHAPTER 18  UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES To compile your updated HelloProgram.il file into a new .NET *.exe, you can issue the following command within a Developer Command prompt: ilasm /exe HelloProgram.il /output=NewAssembly.exe Assuming things have worked successfully, you will see the report shown here: Microsoft (R) .NET Framework IL Assembler. Version 4.0.21006.1 Copyright (c) Microsoft Corporation. All rights reserved. Assembling 'HelloProgram.il' to EXE --> 'NewAssembly.exe' Source file is UTF-8 Assembled method Program::Main Assembled method Program::.ctor Creating PE file Emitting classes: Class 1: Program Emitting fields and methods: Global Class 1 Methods: 2; Emitting events and properties: Global Class 1 Writing PE file Operation completed successfully At this point, you can run your new application. Sure enough, rather than showing a message within the console window, you will now see a message box displaying your message. While the output of this simple example is not all that spectacular, it does illustrate one practical use of programming in CIL round-tripping. The Role of peverify.exe When you are building or modifying assemblies using CIL code, it is always advisable to verify that the compiled binary image is a well-formed .NET image using the peverify.exe command-line tool, like so: peverify NewAssembly.exe This tool will examine all opcodes within the specified assembly for valid CIL code. For example, in terms of CIL code, the evaluation stack must always be empty before exiting a function. If you forget to pop off any remaining values, the ilasm.exe compiler will still generate a compiled assembly (given that compilers are concerned only with syntax). peverify.exe, on the other hand, is concerned with semantics. If you did forget to clear the stack before exiting a given function, peverify.exe will let you know before you try running your code base. 662