CSE P 501 Project V - Code Generation

Due: By the end of the quarter. You should schedule a meeting with the instructor and TA to talk about your project after you've turned it in. If you are working with others, everyone in the group should plan on attending the meeting together. Scheduling is flexible; if you wish, you can finish the project and schedule a meeting before the end of the quarter. Use this turnin form to submit your project.

Overview

The purpose of this final part of the project is to complete the compiler by adding code generation and implementing the runtime support needed to executed the generated x86 assembly code.  Since time is short, you should probably use the simple code generation strategy outlined in class, although you are free to do something different. Whatever strategy you use, remember that simple, correct, and working is better than clever, complex, and not done. You also will get more out of the project if you have simple implementations of more of the language rather than highly optimized implementations of a smaller part. 

Implementation Strategy 

Code generation incorporates many more-or-less independent tasks. One of the first things to do is figure out what to implement first, what to put off, and how to test your code as you go along. The following sections outline a reasonable way to break the job down into smaller parts. We suggest you tackle the job in roughly this order so you can implement the central part of the code generator first, and put off more peripheral topics until the key pieces are done. The experiences gained implementing the first parts of the code generator should give you insights that will ease implementation of the remaining parts. 

Statements & Expressions 

This part of the job includes expressions, statements:

Since no I/O is available at this stage, you won't be able to produce output from test programs. But you should be able to verify that the generated code works by following it in a debugger.

Classes, Objects & Methods

Once you have basic expressions and statements working, add code for objects and methods. Start with:

For now, don't deal with extended classes, inheritance, or related issues. Once you have the basic class/object machinery in place, you can add:

At this point, you should be able to compile and execute substantial programs.

Extended Classes 

Basic support for extended classes requires:

The Rest 

Whatever is left, including boolean variables and assignable boolean values, and any extensions you've added to the project.

C Bootstrap

As discussed in class, the easiest way to run the compiled x86 code is to call it from a trivial C program.  That ensures that the stack is properly set up when the compiled code begins, and provides a convenient place to put other functions that provide an interface between the compiled code and the external world. 

Feel free to embelish the sample bootstrap program presented in class as you wish. In particular, you may find that it is sometimes easier to have your compiler generate code that calls a C runtime function to do something instead of generating the full sequence of instructions directly in the .asm file.

Executing MASM Code with Visual Studio

To execute the .asm file produced by your compiler, you will need to create a Visual Studio project with the C (not C++) main program similar to boot.c and the assembler code from the compiler. The resulting program can be run and debugged using Visual Studio.

The MASM assembler ml.exe is included in Visual Studio .NET and Visual Studio 2003. It can assemble 32-bit code, which can then be linked and executed with other programs, in particular our C main program. You may find it easiest to use the assembler from a command line, but it is also possible to configure Visual Studio to use MASM to assemble the .asm file containing the compiled program. Here's how (or at least, this has been known to work with both Visual Studio 6 and VS.NET).

  1. Create a new Win32 Console Application project in Visual Studio
  2. Add file boot.c (or whatever main program you have created) and the .asm file generated by your compiler to the project. (You may have to change the type of files displayed in the dialog to ``all files'' to see the .asm file.)
  3. Configure the project to use MASM to assemble the .asm file. Select Project>Settings. In the dialog box that appears, be sure that Win32 Debug is displayed in the Settings: field. Expand the file list if needed, then select your .asm file -- and only this file. Click on the Custom Build tab.In the first line of the Build Command(s) field, enter the MASM command to be used to assemble the file.
      ml.exe /c /Cx /coff /Zi ${InputPath}

    (The executable file name ml.exe has a letter l in it, not a digit 1. The InputPath macro can be entered by clicking on button Files and selecting Input Path in the menu that appears.)

    Finally, you need to specify the output file name that MASM should use for the assembled object code. In the Output File(s) field, enter filename.obj, where filename is the name of your assembly source file (without the .asm suffix).

You should now be able to compile, link, and execute your program with the normal Visual Studio Build commands. Visual Studio will use MASM to assemble the .asm file as needed. You can use the symbolic debugger to step through the assembly language code, set breakpoints in it, etc.

What to Hand In

Your online turnin should include

Your group will meet with the course staff after the project is done to discuss it.  This isn't a formal presentation (i.e., don't waste time preparing PowerPoint slides or anything like that).  At that time, you should hand in brief written report summarizing what your compiler does, what was implemented and what was omitted, any extra features you added, and, if you are working in a group, a summary of how the work was divided and who was responsible for what.

If you are working with others, you should turn in only one assignment per group, and all group members should attend the meeting.