Machine Code is for Kids!
Dylan Cuthbert on why machine code is perfect for kids to learn programming
I'm not saying it is the quickest vehicle to take you where you want to go, but conceptually it is non-abstract pure logic and flow, and surprisingly easy to understand. It also gives you the ultimate flexibility and the age-old adage "computers only do what you tell them to do" actually becomes slightly believable. (Note: If you are a programmer, you owe it to yourself to make machine code your bitch, you are actually the omnipotent super-being and machine code honours you with its humble service!)
So back to BASICs (sorry!), BASIC is pretty much just assembler/machine code that has been extruded slightly, given a couple of boosts for ease of use (primarily auto-allocated variables, string manipulation and math notation), and expanded lexically into something more readable. The line numbers are equivalent to memory locations for example and the flow of the program can be directly visualised by simply stepping through the instructions.
Another key important feature of BASIC is that it is bloody slow (and if it isn't you should force it to be by giving your kid an old ZX Spectrum to learn on). This inherent crap slowness is great for kids because it encourages them to explore faster alternatives, and the alternative that is most equivalent to BASIC is actually machine code. Sounds weird doesn't it? I mean, isn't machine code meant to be for hardcore programmers and their ilk and impossible to learn by anyone other than hackers from northern Europe? Well no! For a child machine code is actually the next easiest thing to learn, as thousands of whizz-kids found out in the 1980s.
If you are a programmer, you owe it to yourself to make machine code your bitch.
Poking Digits Into Memory
The system is simple, you have a limited set of instructions, a limited set of registers, and memory (I remember in old machine code books this used to be illustrated by an open hand with a register per finger, that you would then POKE into memory... I can't remember how the memory was portrayed, maybe it was a giant chocolate cake... mmm poking fingers into chocolate cake, well that already sounds FUN!).
Complexity For The Sake Of Complexity
After having this article proofread by a certain machine code madman who goes by the name of Jaymin Kessler, he initially said, "but will kids really understand register spilling, stack frames, register allocation?". He instantly brought in a ton of abstract terminology that was invented primarily for compilers of higher level abstract languages. These are all pre-conceived notions that aren't needed to learn assembler at all – there's no need to even just have one stack in assembler, why not have three? (wait.. C doesn't let you do that so how? oh!) And you might not even use a stack frame at all, it's up to you; there is nothing abstract and pre-decided in machine code apart from the absolutes: memory, registers and instructions. What you do and where you take it from there is for the child's imagination. For example, quite often the stack related instructions in old 8-bit CPUs were used for fast clearing or setting memory, this flexibility is very pure yet easy to understand because it isn't at all abstract.
Twelve Small Steps To Learn Machine Code
To round things up here's a simple list of concepts that a child should find fairly easy to learn (I did):
- 1. Binary – show them how binary values can be visualized by using a monochrome bitmap screen and writing values into it. Show how 8 values can form an 8x8 grid and be "seen" as the letter "A". Ask them to calculate the 8 values to display the first letter in their name.
- 2. Hexadecimal – 8 bit is fine to begin with and then show them fun things such as calculating the decimal value of B00B.
- 3. Registers – visualise them as your fingers, limited in number.
- 4. Memory – a neatly sliced cake or the keys on a piano are good visual aids.
- 5. Instructions for simple math combined with loading and storing. LOAD/STORE/ADD equivalents.
- 6. Looping and the concept of counters.
- 7. Binary math – show them how "shifting right" divides by two and make sure they understand why. Explain XOR/AND/OR and how they can used visually for inversing, blending and masking.
- 8. Explain calling and the concept of return (GOSUB/RETURN should be a concept they are already familiar with from BASIC), and teach them register preservation (a slightly abstract concept but one that is quickly learnt).
- 9. Teach how a single stack works (perhaps combined with 8.) and the concept of push/pop LIFO for temporary storage (in the old-school 8-bit sense).
- 10. Concepts of data structure (relative access methods) and arrays of repeated structure.
- 11. Above all show them how much faster it all runs compared to BASIC, this is the hook!
- 12. Then simply expand and combine all of the above.
BUT BUT...
After writing this and extolling the virtues of BASIC and machine code there is an important saddening point I really have to add and that is that we now live in a day and age where machine code has been so far hidden from us it is actually difficult to find a good platform to give a 10 year old to start on. BASIC doesn't exist anymore either, not as far as I'm aware anyway, so my question to the readership is, given the pre-requisite of "little to no abstraction", do you know of a good replacement for the old BASIC -> Assembler path of learning for pre-teens that produced so many amazing programmers during the 80s and very early 90s?
Please Do Note However: Throughout this article when I am talking about machine code, I am talking about real chips, such as Z80, 6502, 68000, MIPS, ARM, etc, and not about the bastard-child we call x86 architecture or any of its variants. Don't let your children anywhere near that pile of stinking bat poo.