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
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.