CSE 413 -- Assignment 8 -- D Code Generation

Due: Friday, June 4, at the beginning of class. You may work with a partner on this assignment. If you have a partner from the previous D assignments, you should continue working with that person. We will want you to turn in your compiler, and some sample compiled code, details tba.

Overview

For this assignment, add code generation to your compiler. When the finished compiler is executed, it should open a D source program file, compile it, and produce a .asm text file containing an x86 assembly language version of the D program. Source lines from the D file, including comments and whitespace, should appear as comments in the .asm code, with each source line near the code generated from it.

Most of the work in this assignment consists of adding new code to the existing parser. While you may find it useful to create new classes for various data structures or utility routines, the bulk of the changes will be additions to existing parser methods.

Assembly File Format

The MASM assembler source file generated by the compiler should have the following format:

  .386
  .model flat, c
  public D_main
  extern get:near, put:near
  .code

     <your generated code goes here>

  end

This tells the assembler to assemble 32-bit flat-addressing code using 32-bit instructions and registers available in 80386 and later processors. It specifies that the C-language conventions will be used for external names and that get and put are external symbols defined elsewhere (in the code we give you). It also specifies that symbol D_main is an externally-visible name defined in the compiled code.

We have written a very short C main program, Dtest.c that will execute your code (located here). This program calls function D_main (the D main function) and prints the value returned. The code generated for function main in the D program should be labeled D_main, not main. This is needed because file Dtest.c contains the actual function main where execution must begin, so the environment (stack, etc.) is properly initialized before your compiled code is called.

Code Generation Details and Hints

Use the code generation model that was presented in lecture. Some key points:

Executing MASM Code with Visual C++

Your compiler should produce a text file with a name ending in .asm containing the assembly language version of a D program. To execute this code, you will need to create a Visual C++ project with a C (not C++) main program that we will supply and the assembler code generated by your compiler. The resulting program can be run and debugged using Visual C++.

MASM is a complete programming environment for 16-bit assembly language programs. The assembler itself (ml.exe) can also assemble 32-bit code, but cannot link or execute it. For that, we need to use the regular Visual C++ environment. You may find it easiest to use the assembler from a command prompt window, but it is also possible to configure Visual C++ to use MASM to assemble the .asm file containing the translated D program. In any case, you'll need to use the normal Visual C++ 32-bit linker and debugger to execute the resulting program. Here's how to configure Visual C++ to use MASM to assemble and run your generated code the following:

  1. Create a new project in Visual C++ by selecting File>New; click on the Projects tab; select Win32 Console Application for the project type and Win32 for the project platform. Enter a name for your project and select the desired directory, then click OK.
  2. Add file Dtest.c (which you get from us) and the .asm file generated by your compiler to the project. Pick Project>Select Files, then use the Insert Files into Project dialog to add Dtest.c. Do this again to add the .asm file. (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. This includes the full path name for the MASM assembler, the assembly options to be used, and a macro that specifies the input path. In the CSUGlab, the following command should work:
      c:\masm611\bin\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 C++ Build commands. Visual C++ will use MASM to assemble the .asm file as needed. You can even use the symbolic debugger to step through the assembly language code, set breakpoints in it, etc.