Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

dyn-dadeni
So I just made it to chapter 6 of the book, and was a bit disappointed when I learned that we are expected to implement the Hack assembler using some other language. Seems a bit promiscuous to me. ;)

Has anyone else tried to implement a Hack assembler using nothing but the nand2tetris tools?

The biggest problem, as far as I can tell, is coming up with a way to output the results to a file. If I had a better handle on Java and how to implement built-in chips (which I may just have to break down and figure out) then I would implement some sort of persistent storage chip that is memory mapped to overlap with RAM.

However, with test scripts, we have a means of outputting the contents of RAM to a file. I haven't found a way to omit the column header or the column delimiters, but it gets us close enough.

The way I see it, you could write a test script that uses a while loop to run the assembler program until a specific memory address becomes equal to an arbitrary constant, signaling that its work is complete. At that point you could manually copy the contents of the RAM chip by highlighting all 16K rows and paste it into a text editor, where you strip out the line numbers. OR you could use a combination of the assembler program logic and the test script logic to output each instruction to an .out file.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

WBahn
Administrator
You've done a good job of thinking things through, so much of what is below is just emphasizing and perhaps expanding on that.

The Hack computer has no file system, so there is no way to for it to load your assembly code file in the first place.

This is not at all uncommon in embedded microcontrollers -- in fact it's the norm. The first (well, okay, the second actually) microcontroller I worked with had 32 bytes of RAM. Not 32 kilobytes, 32 bytes -- and only 25 of those were general purpose cells. It also only had 512 words of ROM (12 bit words, at that).  Yet it was pretty amazing what you could do with it.

So you write your code on another computer and then run an assembler on it and then download it to the ROM on the device. These were OTP parts -- one time programmable -- so if didn't work properly, you got to throw that microcontroller in the trash, fix your program, and try again with a new part. You can bet I got good at writing error-free programs, or at least programs that only took a few iterations. I didn't even have any kind of simulator, it was all hand verification. The OTP parts were a dollar or two a piece (in 1991 dollars) and I was a poor college student, so it mattered. Enough so that I spent precious money to invest in a UV erasable part and a UV eraser. These parts were about $25 a piece but you could erase their ROM by peeling off a piece of tape over a quartz window and sticking in the eraser for twenty minutes. Since I only had one such part (remember, poor college student) that defined my turn-around time. So the time spent becoming able to write good code on the fist shot still came in handy.

Having said that, I still sympathize with your sentiments. One interesting project you could do would be to develop a file system of some kind and implement it. How this might work is imagine you have another block of memory that is nonvolatile. You can create an interface to it via the existing RAM. You could put an address in, say, RAM[24577] (the next step up from the keyboard) and you put the data in RAM[24578]. You then have another RAM address that issues commands, such as 1 means read and 2 means write. Your peripheral controller would monitor the command address and execute the command when it sees one. You could then have it write to another RAM address with its response. If you wanted to you could have it write to the same RAM cell, but having all cells be written to by only one party is much simpler.

You will need to create some semblance of a file system, but it can be very simple. You could have the file RAM only hold two files, each at a known starting address.

You could need pretty large RAM for your storage. Remember, the .asm and the .hack files are in ASCII. A .hack file that uses all 32k of ROM would be over half a megabyte in size. But you can deal with that easily by using two bytes of RAM for the address as this would give you access to 4 GB of memory.

The problem with trying to use only their tools is that, even if they support having additional memory, that memory will be volatile since they didn't envision it being used that way. Also, the hardware simulator is atrociously slow. The CPU emulator knows about the specified extents of the address space, so it will through an error is you try to access memory outside of it. Writing your own CPU emulator is child's play as long as you don't want keyboard or screen I/O. For what you doing, that shouldn't be a problem.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

dyn-dadeni
I was naively thinking that I could embed the source code in the assembler binary, so it would get loaded when the ROM is loaded. But I forgot that you can't randomly access the ROM as data. I would have to tweak the CPU implementation, which would force me to use the hardware simulator rather than the CPU simulator, resulting in the same performance degradation you described, as if I implemented a non-volatile storage mechanism.

As you may have sensed, I'm trying to relive some of the trials and tribulations that programmers and hardware designers faced in the early days (like the situation you described with the single use ROM chips!) and prove to myself that I can overcome them. Including the fact that at one point there were no high level languages with which one could implement an assembler. But as you hinted at, I'm already cheating massively by using a hardware simulator to begin with!

I do plan to elaborate upon the Hack design eventually, but for now I will just settle for writing the assembler in JavaScript like a normal human being...
Reply | Threaded
Open this post in threaded view
|

Re: Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

WBahn
Administrator
Even if you could access the ROM as data, the fact that each line of assembly code would requite many words of ROM will quickly leave you no room for your assembler code.

We most definitely do not realize how good we have it. I'm old enough to have some appreciation for it (I remember when, in 1981, all of the standalone computers at our school (all five of them) had 4 KB of RAM and the programs were stored on cassette tapes!) except the new Apple IIe that had an ungodly 64 KB of RAM and this thing called a floppy disk drive. I remember asked the instructor what anyone could possibly do that would need 64 KB of memory long before I heard about Bill Gates' supposed similar remark about 640 KB made the same year. The difference is that I actually said it, while all the evidence is that Gates did not (in fact, his position at the time was quite the opposite).

People not much older than me used minicomputers that, in order to boot up if the core memory got corrupted, you had to use switches on the front of the machines to manually program each instruction of the boot loader.

I've never been able to track down the details for a specific instance, but the evolution of the tools in the early days followed a very incremental (and painful) bootstrapping process. Instead of writing an entire assembler, you identified the minimal set of instructions that was needed to write an assembler that could hand those plus a few more. Then you hand coded the assembler for the first version and had it assemble the code for the second and so on. I'd love to find the actual details of this happening and learn how many steps it took to support the entire instruction set and how many instructions were supported at each stage (but especially the first one).

Reply | Threaded
Open this post in threaded view
|

Re: Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

Lozminda

I recommend computerphiile on youtube

https://www.youtube.com/watch?v=QFK6RG47bww&list=PLzH6n4zXuckqZ90zLyy36qjO5YIn1RulG

Professor Brian Kernighan talking about Bell labs. And his time there. Computerphile has it all, bootstrapping, assembly, early compilers etc etc.

Numberphile has Jon Conway talking about his game of life too, if you fancy a deep nerd
Reply | Threaded
Open this post in threaded view
|

Re: Implementing the Hack Assembler... In HACK MACHINE LANGUAGE!

dyn-dadeni
Yes, I'm a big fan of computerphile. Didn't realize they had so many videos about the bootstrapping problem, but their videos about computing history are some of my favorites.