Arithmetic Logic Unit & Assembler

As you know, as part of the Advanced Programming course we are doing part of the nand2tetris course.

The nand2tetris people supply a software suite in the form of a zip file containing some simulators and projects for the course.

  1. In a terminal, go to the directory where you keep your assignments. Do something like this…

    wget https://advprog.auc-computing.nl/code/nand2tetris.zip
    unzip nand2tetris.zip
    chmod +x nand2tetris/tools/*.sh
    alias hw=~/nand2tetris/tools/HardwareSimulator.sh
    cd nand2tetris
    git init
    git add projects tools
    git commit -m "nand2tetris unzipped"
    
  2. One by one, you should now write the code in each of the chip files in projects 1 and 2. Let's do Not.
    1. First run the hardware simulator on the test for Not

      $ hw ./projects/1/Not.tst
      Comparison failure at line 2
      

      It runs but fails because we have not written any code for the Not chip.

    2. To add code for the Not chip, edit the file Not.hdl and where it says

      //// Replace this comment with your code.
      

      put this line

      Nand(a=in, b=in, out=out);
      
    3. Now run the hardware simulator again.

      $ ./tools/HardwareSimulator.sh ./projects/1/Not.tst
      End of script - Comparison ended successfully
      
    4. Now continue with other chips until you have a working ALU.hdl chip.
  3. For the second part of the assignment, your task is to write a Python program that works in the same way as the nand2tetris assembler. Let's first make their assembler executable.

    chmod +x ./tools/Assembler.sh
    
  4. In the projects/6 directory there are three subdirectories which contain programs written in assembly. The simplest of these is Add.scm. Let's run the nand2tetris assembler on it.

    ./tools/Assembler.sh projects/6/add/Add.asm
    
  5. This writes a file called Add.hack Let's have a look at it's

    $ cat projects/6/add/Add.hack
    0000000000000010
    1110110000010000
    0000000000000011
    1110000010010000
    0000000000000000
    1110001100001000
    
  6. Now write your assembler! You should be able to run it like this. With the output from Add.asm you can check by eye that it is the same as the output from Assembler.sh.

    ./assemble.py < projects/6/add/Add.asm
    0000000000000010
    1110110000010000
    0000000000000011
    1110000010010000
    0000000000000000
    1110001100001000
    
  7. You can make a direct comparison with the diff command. If this gives no output then the outputs of the two assemblers are identical.

    diff projects/6/add/Add.hack <(./assemble.py < projects/6/add/Add.asm)
    
  8. Now try it on the pong program. It's assembly is many lines long so you will not be able to compare it by eye.

    wc projects/6/pong/Pong.asm
     28378  28481 200041 projects/6/pong/Pong.asm
    

    If your assembler gives identical output to the nand2tetris assembler, you can be pretty confident that your assembler is good!

    ./tools/Assembler.sh projects/6/pong/Pong.asm
    diff projects/6/pong/Pong.hack <(./assemble.py < projects/6/pong/Pong.asm)
    

Author: Breanndán Ó Nualláin <o@uva.nl>

Date: 2026-04-02 Thu 11:52