https://new.jameshunt.us

Learning Assembly... Why?

I started learning assembly a few weeks ago. Assembly?? Yeah. Assembly.

I've been slinging code for at least a decade. I've written C, Ruby, Basic, Perl, Lisp, Scheme, Haskell, Node/Javascript, Go, Lua and Erlang. I would consider myself proficient in half of those, competent in the other half. I believe strongly in higher-level languages. If you can express what you want to do in as few constructs as possible, why use a less powerful language?

But I always find myself drawn to assembly.

I think the reason lies in the fact that machine code is inescapable. Everything ends up as machine code, because its the one and only language the machine speaks. C is arguably a thin wrapper around assembly, abstracting memory architecture and calling conventions. Interpreted languages like Javascript run through a virtual machine that is itself written in, ultimately, machine code. Though the Perl programmer doesn't sweat memory management, the machine does.

After reading Paul Graham's Beating the Averages, I took up his unwritten challenge to learn and use Lisp. Lisp is a beautifully simple language, and its elegance affords the programmer ultimate flexibility, with a little work. Compared to Lisp, assembly is a constrained, weak language, confined to the few operations the machine understands. Put a bunch of bits here. Put some more bits over there. Check this bit, set that bit. Bits, bits, bits, bits. There are no lists, strings, or objects. Math is confined to the arbitrary size limits of the processor.

And yet a Lisp interpreter is ultimately expressed in terms of these primitives. Assembly is the base. Everything else is just an abstraction.

I didn't set out to learn assembly for the usual reason of performance. What caused me to take the plunge and dive into assembly was language design.

For a personal project, I began writing a domain-specific embedded scripting language. Let's call it Q. Under the hood, Q expressions are implemented as binary parse trees, like most other languages. The parser builds up these trees in memory, and the run-time walks the tree and executes actions for each op-code.

Q functions are expressed as self-contained parse trees that are evaluated for every function call. Named functions are just parse trees linked to one or more symbol tables. Scope is implemented by keeping a stack of symbol tables, one per scope.

What started out as a niche language with specific requirements morphed into a general purpose language. I blame Lisp for this. With a little bit of work and a couple dozen more parentheses here and there, Q could become a Lisp dialect.

Yawn. Boring. How many Lisp-y languages are out there? Ten? Twenty? More? Don't get me wrong, Lisp is awesome. But like other high-level languages (I'm looking at you, Perl/Ruby/Python), it requires an interpreter. Someone wrote some kick-ass program in Erlang? Gotta install the interpreter and standard libraries. Python? Get the interpreter. Ruby? You guessed it, you need an interpreter.

Wouldn't it be awesome to create a language (Yes, yes. I am aware that Go has a unique ability to compile down to machine code.) with the elegance of Lisp and the speed of raw machine code?

Enter assembly.

I figure if I know assembly well enough, translating Q parse trees and symbol tables into machine code should be fairly trivial. Patterns tend to bubble up from the most foundational levels of computer science. Q's design follows the Von Neumann architecture, which maps cleanly to real hardware architectures, and by extension, assembly.

Underlying all of this is my personal drive to learn. Learn anything. Learn everything. It's why I got involved in computers in the first place. And although my logical reason for wanting to learn assembly are shaky at best (do we really need another Lisp? Probably not) the illogical reason is good enough for me.

Why do you pursue your passion?

James (@iamjameshunt) works on the Internet, spends his weekends developing new and interesting bits of software and his nights trying to make sense of research papers.

Currently exploring Kubernetes, as both a floor wax and a dessert topping.