
Why Learning Assembly Language Is Still a Good Idea (2004) - jacquesm
http://onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html
======
ANTSANTS
I don't think programming in assembly language for modern architectures
(x86-64 as implemented by the latest Intel/AMD chips) will ever be as fun as
doing so for microcontrollers or embedded devices, because it's almost
impossible to keep all of their inner workings in your head.

A 6502 is a really stupidly simple machine. If you've had previous exposure to
programming in assembly, you can get a pretty complete understanding of the
machine in an afternoon. It doesn't take very much experience to get to the
point where you can take a look at a subroutine and figure out exactly how
many cycles it will take to execute, on which exact cycle this I/O operation
will occur, etc.

I've tried that approach with x86 (not even x86-64!) manuals before, and I ran
away screaming. I don't know how long it would take me just to be aware of all
of those instructions, let alone be able to even roughly estimate their
execution time across the hundreds of differing x86(-64) implementations! Just
peeking at Agner Fog's optimization manuals[1], I remember that some
instructions can take 20~ cycles on a Pentium 4 (probably the oldest x86
processor still in common public use), and 1~2 cycles on anything past the
Core series. Some instructions an Intel Atom will choke to death upon. With
some similar pairs of instructions, one of the two is faster on every machine
_except_ the Atoms! How am I supposed to reconcile all of these discrepancies
and write something that is anywhere near optimal for a large portion of the
x86 userbase?

You can make the argument that you don't need to know all of the x86
instructions to write a decent assembly language program. That's probably
true. Yet, part of the fun of working on a simpler system is that you can
write a piece of code and know that it is very close to optimal -- maybe you
could rewrite the whole thing and save a few bytes or a few cycles, but you
still feel like you've put your repertoire of tricks to good use and made
something that you would be feel reasonably comfortable showing off to the
experts. If I can't get that feeling on x86, only getting to beat a compiler
that has to work within the limitations of its language, and producing a
result where no one really cares (and can't even tell!) that I shaved a few
cycles here and there, there is little point, and not as much fun.

If you want to have fun writing assembly language, pick a processor
microarchitecture that you can comfortably fit in your head, and an
environment where you'll only have to deal with one or two implementations of
that microarchitecture. Intel and AMD, in the (very well justified) interest
of developing the most powerful machines on the market, have turned x86 into
something that is not fun to write assembly for, and not possible to fit in
your head (at least, without serious commitment on the level of "I am going to
make a career out being the x86 guy/gal"). Don't bother! Don't even bother
writing something for a platform where you need libraries to print something
to the screen, or convert a line of text into a number. Find a platform that
lets you turn lights on and off by poking addresses, and go from there.

In the mean time, I'm not at all surprised that no one tries to write optimal
software for x86 PCs. No user will feel the effort you put into shaving cycles
off of anything but the tightest loops and most critical of paths, and there
isn't even a scene of ``expert programmers'' comparable to the ones currently
around the 6502 or 68000 to appreciate what you do. The best you get is a
mention on Hacker News and a few wistful comments about the good ol' days.

</stupid rant>

[1] <http://www.agner.org/optimize/>

Lots of very useful information here, even if you don't ever want to attempt
programming in x86 assembly.

EDIT: The funny thing about all this is that even ``back in the day,'' a 6502
was fast enough that you could get away with all kinds of inefficiencies. You
find a game that blew your mind as a kid and stuff it into a debugging
emulator, trying to understand bits and pieces of how the engine works, and
find yourself laughing at trivial inefficiencies all over the place, even in
critical loops! Yet, even with all the hundreds or thousands of bytes and
cycles wasted here and there, then end result still feels plenty ``fast.''

~~~
whatshisface
> _If you wanna have fun writing assembly language, pick a processor
> microarchitecture that you can comfortably fit in your head, and an
> environment where you'll only have to deal with one or two implementations
> of that microarchitecture._

For those of you who read this and want to try it out, I highly recommend the
Propeller. The transistors were for the most part laid out by a single guy,
using only his brain and the silicon-tracing equivalent of notepad, but it is
powerful enough to run about the same applications you might find on a
commodore64.

<http://www.parallax.com/propeller/>

~~~
dkersten
I've also had a ton of fun doing this for PIC24 (the 16bit PIC family of
microcontrollers), which has an incredibly straightforward instruction set.
They're also quite fast, as far as microcontrollers go and while I do love the
Propeller architecture, the 8-core goodness makes them a little more complex
to thoroughly understand (though their deterministic nature and the fact that
you can actually count cycles reasonably easily makes them less complex than
most multi-core processors)

------
dochtman
Having worked with assembly a little bit (MIPS, for Coursera's Compilers class
-- but it's supposed to be better than x86!) and with LLVM IR a bit more (I'm
writing my own compiler for a language that compiles to IR), I really wonder
about the trade-offs for learning LLVM IR vs assembly if your goal is to learn
lower-level details.

In particular, LLVM IR is just so much easier to use, even though it lives at
a very similar level as "real" assembly. Granted, you don't have to take care
of register allocation yourselves, and the instructions are slightly more
abstract (an abstraction which is inevitably leaky), but it does really drive
home the differences between registers and memory, how pointers and addressing
are used at the lower level, that there are different calling conventions (but
you don't have to learn the niggly little details for each), it's portable,
etc.

Anyone who has used both more extensively who can comment?

------
unimpressive
If more of the "how to do X" articles focused on formal verification/etc or
assembly routines, I wouldn't feel as much that HN is bogus.

And since it was actually relevant, I will reproduce SparrowOS's comment
below:

"If you love programming more than anything, you are probably the kind of
person who wants to know assembly language. If your full heart is not into
programming, maybe not."

~~~
jacquesm
It doesn't help that the SparrowOS dude is certifiable.

~~~
TallGuyShort
Yeah what's the deal there? I always assumed he was a spam bot...

~~~
phaus
He's schizophrenic and the parts of his comments that look like spam are
actually algorithmically generated Christian songs.

~~~
chc
Lest anyone take this as a mean-spirited joke: This is the actual truth. He
suffers from schizophrenia and has a long-standing interest in algorithmically
generated Christian messages, which he seems to find meaningful.

------
networked
If starting with x86 assembly seems overwhelming to you there are a few
alternatives that might help.

First are virtual machines that were developed to be programmed directly in a
kind of assembly language. CHIP-8 [1] is a good example of one of those, being
a VM standard developed to make games run across a broad range of otherwise
incompatible mid-1970s hardware. It gained a new popularity in the early 2000s
and as a result you can now find CHIP-8 emulators for virtually any platform,
including your mobile phone, as well as a range of assemblers and other
development tools. It's a fascinating bit of history in its own right and also
a great platform to emulate in the first emulator you write. A bit further
away from the syntax of "real" assemblers is Linoleum [2], which is meant to
be a kind of a cross-platform assembly language targeted towards graphics
applications, but the principles behind programming in it are largely the
same. I can recommend both from personal experience, although CHIP-8 is
probably a better starting point.

Second, if you want something closer to real hardware I'd suggest learning how
to program for the MOS 6502, the CPU used in the Apple II and (with some
modifications) in the Commodore 64 and the NES gaming console. One way to get
started with it is Easy6502 [3], which is an online introductory course on
6502 programming bundled with an in-browser emulator.

[1] <https://en.wikipedia.org/wiki/CHIP-8>

[2]
[https://en.wikipedia.org/wiki/Linoleum_%28programming_langua...](https://en.wikipedia.org/wiki/Linoleum_%28programming_language%29)

[3] <http://skilldrick.github.com/easy6502/>

------
fnordfnordfnord
Randall Hyde is a boss. I was thinking about him the other day. I used to read
everything of his that I could find when I was taking courses at a place that
had no Randall Hyde. I couldn't find a reference to it, but he used to have an
annual-ish day of destruction for insolent computing equipment.

Nowadays I'm an electronics instructor at a JuCo. I don't teach any assembly.
I barely mention it. It was in the curriculum, and I specifically threw it out
[1]. There just isn't enough time to do everything, that everyone might want
us to do. I replaced it with Python and C [2].

C lets us get to building systems much quicker.

C covers more potential job opportunities than any particular architecture,
and no company can ever have a monopoly on C. C is portable assembly language.

Most people [3], when faced with the choice of optimize vs buy a better
microcontroller, they spend the extra two bucks.

Even though solving problems with assembly can be tremendously fun and
fascinating, I still prefer C. (sorry Randall).

[1] But I'm always interested in good arguments about the subject.

[2] and LabView, I'm embarrassed to say.

[3] people also includes the companies that hire our graduates.

~~~
JoeAltmaier
Eventually every high-level programmer gets a fault on a line of code. It may
contain five or six dereferences, some temporary constructors, result
assignment.

Without knowing assembler it can be impossible to discover exactly which was
at fault. The programmer can thrash around for half a day swearing and
struggling.

And also, did I just call 'C' a high-level language?

~~~
fnordfnordfnord
>>Eventually every high-level programmer gets a

I'm hoping that any of my JuCo grads who go on to get real programmer jobs
(there have been a few) will get some more practice/training, than I can give
them in a couple semesters; maybe find a mentor to work with for a bit too.

>>Eventually every high-level programmer gets a... And also, did I just call
'C' a high-level language?

Sure looks that way ;)

------
KaeseEs
In the domain I work in (firmware for digital instruments and industrial
systems), knowing assembly isn't necessary for performance reasons so much as
for sanity reasons - a lot of vendor compilers for embedded devices are
incredibly flaky, and if you can't inspect the generated assembly you'll never
know what the hell is going on in cases where the code doesn't behave the way
you expected it to.

Heck, even when I have the privilege to be treading a more well-worn path (eg.
ARM/GCC), it's helpful to be able to tell what the compiler is transforming
(on a less charitable day I'd say "munging") my code into.

~~~
JoeAltmaier
Very much agree. Assembler is not about efficiency; its about debugging.

------
c3d
The article focuses on writing great code, but there's another reason to learn
assembly language: for some specific aspects of a machine that were not
modelled in the higher level languags, this may be the only way to go.

For example, for HP Integrity Virtual Machines (sort of VMware for HP big iron
servers), I spent a lot of time writing low level vector code that just cannot
be written in any other language because it executes in some specific
restricted environment that the C compiler cannot deal with. Specifically, it
runs off a few reserved registers, has no valid stack (a TLB handler may be
triggererd by a TLB miss on the stack), and frequently use instructions that
are at best supported by compilers as inline assembly.

So it's not just about performance or style, it's also about semantics. And
that's part of the reason why in XL, all low-level operations are connected
with the machine explicitly. I reasoned that what worked for an addition would
alo work for a more bizarre machine instruction.

So in XL you have for the imperative dialect:

    
    
        function Add(x,y:integer) return integer written x+y is XL.Bytecode.Add
    

And for the functional dialect:

    
    
        X:integer + Y:integer as integer -> opcode Add
    

The list of opcodes is machine specific, but the way to connect to them is
not.

Does not solve the whole problem, e.g. The compiler still has to assume things
like "there's a stack", but getting closer to connecting machine and high
level languages.

------
eduardordm
I used to teach OS classes a local university, every summer I would teach 3 to
5 students how to build a bootstrap and a simple 'kernel' just using asm. The
rest of the class would just use GRUB and do something better, faster.

Anyway, I don't think this matters to our usual professional life.

(this person deserves to be heard, he built a large OS, dead comment)

he wrote:

"If you love programming more than anything, you are probably the kind of
person who wants to know assembly language. If your full heart is not into
programming, maybe not."

------
zxcdw
When will we be in a world when we don't have to deal with assembly language
at all? When can we just get the job done without having to understand or know
any of the things which go down there? Because that stuff pisses me off. Bits?
Bytes? I just want that freaking login box and implement some functionality
and _never have to deal what's under_. Is it _really_ that hard? Sigh.

~~~
jacquesm
When will we be in a world when we don't have to deal with molecules at all?
When we can just get the job done without having to understand or know any of
the things which go down there? Because that stuff pisses me off. Protons?
Electrons? I just want that freaking light to come on and implement some
functionality and _never_ have to deal [with] what's under[neath]. Is it
_really_ that hard? Sigh.

\--

I don't particularly like that style of arguing a point but this is just
asking for it. Knowing a higher level of abstraction without knowing a lower
level of abstraction is just fine. But knowing a lower level of abstraction
will give you a definite edge and if there is one thing that hackers are
always looking for then it is a way to have an edge over the rest. A way to do
something that is deemed impossible simply by knowing a bit more, a way to
achieve some feat by exploiting knowledge that is maybe a bit harder to come
by but not impossible. The ultimate level playing field, you get as many tools
as you're willing to learn how to use, with only your attitude towards
learning and your perseverance as the limiting factors.

~~~
joezydeco
I was going to write a similar analogy, but not as abstract as that. I was
thinking more like the automotive industry.

Most people want to just be able to buy and drive it off the lot without
having to understand how it works or what makes it tick inside. But there will
always be a need for automotive engineers.

~~~
greenyoda
Also, knowing a bit about how your car works will make you less likely to get
ripped off by a dishonest or incompetent mechanic.

~~~
tjoff
Also it will make you drive better and more efficient as well as care for it,
resulting in a far less need of an mechanic in the first place.

------
dizzystar
Ten years later, this article still resonates on so many levels. I hope we
reach a day that we all aspire to like those that refuse to download the next
x-behemoth flavor-of-the-day framework for all the reasons stated in this
article instead of deriding them.

~~~
demian
I hope only the best frameworks and tools, written by the best programmers,
get stadarized, so the application developers can focus on business logic,
data science/engineering and interaction design with a robust abstraction
below.

~~~
regularfry
If the _best_ ever won out, that might be a rational hope.

