> I just can’t fathom how he was able to do that.

Honestly, it's not that hard. Not for a decent assembler.

The "hard parts" of assembly are things like trying to do multi-precision stuff on smaller precision machines (like 16- 32- bit math on an 8-bit processor). Just coming up with the tiny algorithms we all take for granted. Of course, today, you don't have to invent those.

Folks think that written in assembly is all bit twiddling and high, dense data structures. But that's not necessarily true.

On a modern x86, it's not that much different from normal C in terms of data sizes and data structures. 16- and 32-bit registers. Add/Sub/Mult/Divide instructions. Block move instructions. Modern assemblers handle structured data. Stupid assemblers handle offsets readily. Assemblers handle local and private symbols, exporting routines, code modularity. You don't have to worry about addresses and what not, linkers do all of that. Symbolic debuggers like anything else. Not like they have to burn a PROM and shove it into a board every dev cycle.

But, most important, once you've got started, once you have the common elements of programming (parameter passing, looping, math, structures, pointer dereferencing), I mean, that's it, right? Rinse and repeat. That's what higher level languages give you "for free". Not every line is hand crafted, hand optimized, etc. Much of it can be stomped out with macros for anything that takes more than a few instructions. Tada -- you now have a higher level language (for small values of "higher").

If anything it's just more tedious. Less code density (assuming little macro use) per screen, etc. But even then, once you have your momentum, once you have your routine patterns, they just fall out of the code as you read it.

I remember my assembly class in college (I was not a good college student). I stopped going to class because the teacher kept asking me system questions. She gave me an incomplete, and I had to do all the projects again next term (that was, honestly, quite nice of her -- she could have just failed me).

So, I did those projects. Those simple Assembly class projects. Trivial little programs "Convert decimal to binary" type stuff.

What I did was I wrote a large macro library, inspired by Forth. I basically ported a rough Forth vocabulary to assembler macros. That "convert decimal to binary" project?

; Convert 10 to Binary and print it
PUSH 10; PUSH 2; PUSH BASE; STORE; PUSH BUFFER; NUMBER; PUSH BUFFER; PRINT

So I turned in my projects, each one was like that -- 10, 20 "instructions". I said "Here's my projects", handing 10, small, 2-3 page printouts, "but you'll need this to understand them" and I gave her a 3/4" thick printout of the macro library.

Yea, I was kind of a jerk. Just where my head was at.

Figured I'd get an F or and A. She gave me an A. (I mean, if nothing else, I did demonstrate a solid understanding of assembly language programming!)

But the underlying point is that it's just patterns, patterns we get used to using and writing. It can be inscrutable to the uninitiated, but the curve, particularly on modern processors, is not that steep. Like I said, you're not just shifting and adding to multiply anymore like the old days. And staring at a disassembly of raw code is not the same thing as writing assembly language with modern assemblers.