The Elements of Computing  Systems / Nisan & Schocken / www.idc.ac.il/tecs 

Project 6:
The Assembler

Objective: Develop an assembler that translates programs written in Hack assembly language into the binary code understood by the Hack hardware platform. The assembler must implement the Translation Specification described in Chapter 6, Section 2.

Resources: The only tool needed for completing this project is the programming language in which you will implement your assembler. You may also find the following two tools useful: the assembler and CPU Emulator supplied with the book. These tools allow you to experiment with a working assembler before you set out to build one yourself. In addition, the supplied assembler provides a visual line-by-line translation GUI, and allows online code comparisons with the outputs that your assembler will generate. For more information about these capabilities, refer to the Assembler Tutorial (see the Tools section in this site).

Contract: When loaded into your assembler, a Prog.asm file containing a valid Hack assembly language program should be translated into the correct Hack binary code and stored in a Prog.hack file. The output produced by your assembler must be identical to the output produced by the assembler supplied with the book.

Building Plan: We suggest building the assembler in two stages. First write a symbol-less assembler, i.e. an assembler that can only translate programs that contain no symbols. Then extend your assembler with symbol handling capabilities. The test programs that we supply for this project come in two such versions (without and with symbols), to help you test your assembler incrementally.

Test Programs

Each test program except the first one comes in two versions: ProgL.asm is symbols-less, and Prog.asm is with symbols.

Program Description Symbol-less version

Add.asm

Adds the constants 2 and 3 and puts the result in R0.

Max.asm

Computes max(R0,R1) and puts the result in R2.

MaxL.asm

Rect.asm

Draws a rectangle at the top left corner of the screen.  The rectangle is 16 pixels wide and R0 pixels high.

RectL.asm

Pong.asm

A single-player ping-pong game. A ball bounces constantly off the screen's “walls.”  The player attempts to hit the ball with a bat by pressing the left and right arrow keys. For every successful hit, the player gains one point and the bat shrinks a little to make the game harder. If the player misses the ball, the game is over. To quit the game, press ESC.

PongL.asm

The Pong program was written in the Jack programming language (Chapter 9) and translated into the supplied assembly program by the Jack compiler (Chapters 10-11). Although the original Jack program is only about 300 lines of code, the executable Pong application is about 20,000 lines of binary code, most of which being the Jack operating system (Chapter 12). Running this interactive program in the CPU emulator is a slow affair, so don't expect a high-powered Pong game. This slowness is actually a virtue, since it enables your eye to track the graphical behavior of the program. In future projects in the book this game will run much faster.

Steps

Create a directory named projects/06 on your computer and extract project 06.zip to it (preserving the directory structure embedded in the zip file).

Write and test your assembler program in the two stages described above. You may use the assembler supplied with the book to compare the output of your assembler to the correct output. This testing procedure is described next. For more information about the supplied assembler, refer to the Assembler Tutorial in the Tools section.

Tools

The supplied assembler: The practice of using the supplied assembler (which is guaranteed to produce correct binary code) to test another assembler (which is not necessarily correct) is illustrated in the following screen shot and explanation.

Let Prog.asm be some program written in Hack assembly. Suppose that we translate this program using the supplied assembler, producing a binary file called Prog.hack. Next, we use another assembler (e.g. the one that you wrote) to translate the same program into another file, say Prog1.hack. Now, if the latter assembler is working correctly, it follows that Prog.hack = Prog1.hack. Thus, one way to test a newly written assembler is to load Prog.asm into the supplied assembler program, load Prog1.hack as a compare file, and then translate and compare the two binary files  (see Figure 6.3). If the comparison fails, the assembler that produced Prog1.hack must be buggy;  otherwise, it may be OK.