# Is it worthwhile to teach assembly nowadays?

In the 80s, it was common for CS students (and anyone wanting to do "real" programming) to learn assembly. After all, if you needed speed, hardware access (including direct output to monitor) or working on low powered hardware, you needed Assembly.

But nowadays, in 2018, assembly is pretty much useless except to bootstrap an OS or for compilers (and even that isn't as important as it used to be since LLVM took off).

So is there still a use in programming Assembly?

• This discussion could be useful. – user58697 Jan 22 '18 at 6:57
• We teach little man computer, to help teach how computers work. Don't teach x86 it is too complex. LMC is a good first assembler (not a real CPU, but a simulation for learning). A good real CPU, for those that want one is ARM, but better to use high level, unless creating a compiler / dispatcher / memory manager. – ctrl-alt-delor Jan 22 '18 at 18:32
• I guess it would be really useful to the retro-gaming industry. Retro-gaming industry has been really popular lately due to nostalgia. I think that writing an emulator requires a knowledge of assembly. – LateralTerminal Jan 29 '18 at 20:05

I think so, yes. However, I also believe teaching assembly isn't valuable because it could hypothetically teach students how to write "faster programs" -- compilers these days are smart enough that most of the time, you're just better off using a systems language and relying on the compiler if you're interested in that.

Rather, I believe the value in teaching assembly (and systems in general) is it gives the students a much deeper understanding of how computers work, which is highly valuable if they want to move on to other subfields of computer science.

For example, suppose a student is interested in exploring security. If they want to learn how things like buffer overflows work, what ASLR is, be able to understand the latest innovations in kernel research, how whatever the vulnerability-of-the-day works (right now, it seems to be Spectre and Meltdown), it's essential they have a good understanding of how exactly their computer, the hardware, the OS ticks.

Teaching assembly (and more importantly, things like calling conventions, the stack vs the heap, and so forth) is a pretty decent stepping stone to help prepare students travel down this path. Of course, I'm not claiming teaching assembly is the only way, but it's certainly a well-trodden and popular route.

We can do the same kind of analysis for other fields -- systems knowledge is potentially valuable for people interested in compilers/PL research, in software validation and correctness analysis research, for people who want to build on top of new tools like Webassembly, for people who are interested in writing hardware accelerated code (using GPUs, FPGAs, SIMD instructions, etc)...

Of course, not everybody is going to be interested in these fields, and even if they are, that doesn't necessarily mean that assembly is going to be directly useful or relevant to them.

But I don't think that's any excuse not to teach the material -- the goal of teaching, I believe, is to prepare students to be successful in a wide variety of different fields, whether that's industry, research, or something else. And if that means sometimes teaching them material that they won't directly need for the foreseeable future, I think that's fine. It's better to be over-prepared then under-prepared, yeah?

tl;dr: having systems knowledge is useful. And if you're going to teach systems, I would imagine that you're basically obligated to teach at least some assembly.

• Also, some practice of assembly makes the notion of pointer (location containing an adress) really obvious. – Michel Billaud Jan 22 '18 at 10:20
• I remember having a big gray area between hardware and software before learning assembly. I think being able to trace your code all the way to the physical objects it controls is important. – gunfulker Jan 22 '18 at 22:15

It may not be as essential today to teach a particular assembly language to students. It certainly isn't necessary for them to learn assembly language early in their education, especially first.

However, every person who wants a solid understanding of computing needs to know at least the principles of assembly language and its components: registers, memory, busses...

It is even necessary to know something of the even lower level things on which assembly language is built: transistors, gates, adders, ...

The reason that this is essential is that computing is built on a layered architecture of abstractions and not understanding this is crippling - even to a programmer writing relatively pedestrian application.

In my view, however, the education should start at a relatively high level of abstraction, such as (for example only) object oriented or functional programming and then work from there. Mostly the programmer works upwards from the abstractions defined in a language and its libraries, but to really understand what is going on and to appreciate why the yet higher levels we build are based on the lower levels it is necessary to know at least fundamentals of the entire abstraction "stack".

Sometimes, as in writing compilers or device drivers it is necessary for the programmer to work downwards, of course, but even when the individual doesn't need to do that, the tricks and techniques used to build higher and higher are useful to know so that you can fall back on older techniques when hard problems are encountered.

But real assembly language is messy. You needn't burden every student with all of the details in order to convey (and practice with) the essentials. When I taught compilers, the students compiled a high level language against an abstract (defined by me) assembly language level. That level was itself built on lower levels that the students (most of them) didn't need to explore in detail as their target level was sufficiently low for them to practice with registers, jump-logic, memory fetching, etc.

• The messiness depends on the assembly. ARM is less messy than x86, and arguably more useful too. – Peter Taylor Jan 23 '18 at 8:28
• Arm assembler is still pretty messy, it just has different types of mess to x86. – Peter Green Jan 28 '18 at 3:40

I may be biased by being a computer architect, but I would not consider a Computer Science education complete without knowledge of what a computer actually is. This includes having a general idea about all the levels, from the logic gate up through assembler, OS, compiler, to the application programming. It doesn't have to be deep knowledge and it doesn't have to be a real assembly language (although IME real languages tend to have better supported tools and feel more "useful" to students), but after graduating the students should have a better answer to "how did we make rocks think???" than "¯\_(ツ)_/¯ magic".

However, not all education is a 4-year CS degree. For more specialized courses, like 2-year vocational programming degrees, it often won't make sense to include. You won't be able to teach how compilers work effectively without some basic assembly knowledge, but an application developer doesn't need to know that, they just need some general idea of what type of operation is fast and what is slow. A web developer has no need for assembly whatsoever.

It depends on the level you're teaching.

You certainly don't need to introduce assembly language in the first year, and you certainly don't need it to "get stuff done" or to make a "real" application. You can put together a website, a server, an Android app, dabble in robotics and artificial intelligence, all without knowing a thing about assembly language. So do you need assembly language? No.

But advanced students (at the university level) should have the option of learning more about assembly language if they're curious. The other answers do a good job of outlining why they should be curious. But I don't think it should be a requirement. I've had a pretty good software engineering career, and I don't think I've ever had to know anything about assembly language.

tl;dr: Offer it as an elective and see how many students are curious.

Is it worthwhile to teach assembly nowadays?

Yes

If you are trying to write a compiler that compiles down to machine code, write a device driver, do a crash dump analysis, debug a program running as machine code, do computer forensics, be a white hat hacker, etc., then you need to learn assembly programming and thus it still needs to be taught.

They should definitely write a dozen lines of ASM, at least an hour of lesson. It helps to understand compilation and it's interesting to know what the processor instructions are. It introduces the students to the concepts of SSE optimizations, processing order, it's used by some security professionals and hackers, It's used by those that require high degrees of optimization for maths code that doesn't compile into the best order. The language itself requires a different logic to other codes, and It's a fun mental exercise to sort lines into fast sequences.

I woudln't do more that a day of it though. If the student has 1 day of ASM experience, he will know well what it means when he sees it mentioned, as it frequently is, and he will know more thoroughly about information technology.

• I'm not an educator (except on SO) but I don't think it's very plausible to get to SSE / AVX (x86 SIMD) in 1 day if starting from scratch, with students who don't yet know about registers and instructions / control flow. A lot of SO questions have code with jmp foo / foo: (i.e. jump over whitespace in the source to the next block of code). IDK if that's sometimes left over from moving blocks around, but very often there's a lack of understanding that execution continues to the next instruction on its own unless you specifically stop it. (Maybe branchless / SIMD code is actually easier?) – Peter Cordes Feb 23 '18 at 6:38

As others have already mentioned it depends on the level of education and maybe of interest.

In college I had to study assembly for microcontroller programming. Although the 80s are a long time ago, ASM is a good language for DIY projects with small controllers like pic. Even the good old 8086 is still used.

At the university, we used assembly - as mentioned in the question - for OS bootstrapping. I think, especially in CS, it's good to know what happens when you start the operating system. Just to demystify all the magic happening at system start.

It became especially important in the malware analysis. Programs were compiled and reverse engineered. C code -> machine code -> assembly code and vice versa.

This gave a good insight into the workings of compilers and processors and how, for example, even machine-level data types are handled.

As Allreay said, it depends on the level of education and the audience.

# For this reason NO.

In the 80s, it was common for CS students (and anyone wanting to do "real" programming) to learn assembly. After all, if you needed speed, hardware access (including direct output to monitor) or working on low powered hardware, you needed Assembly.

It has been shown that as lines of code increase performance decreases. As assembler programs grow there performance drops. It is hard to write big programs in low level languages. You can not consider all of the low level stuff and all of the high level stuff at the same time. Therefore choose a language that keeps lines of code low. (This is not the only factor.)

Even if you make a highly optimised assembler program, that is faster than the high level alternative. It will not be faster (or won't work), on a different processor: Different optimisation decisions need to be made for 386, 486, 586, 686, x86-64. However if an [efficient] high-level language is used, then you just recompile your system (or get someone else — such as Debian — to do it), and you have a new faster system. The assembler code stays slow, until re-written.

# Reasons of Yes

• As a tool to gain a better understanding of the computer (as part of computer science).
• As part of a compiler course.
• As part of an operating system course, when writing a few components: part of thread dispatcher (may come with compiler/libraries), part of memory management (controlling mmu), memcpy fast memory copy (part of compiler/libraries), interrupt dispatching.

Note I say part of. I have done this for a commercial product. I kept asking how much of this needs to me assembler. I kept being told this dose, I would push back and say no just this line of this routine, so call out to another routine that is implemented in assembler (the compiler will do call optimisation: in-lining). We got an operating system down to 10 to 20 lines of assembler (not including what was in compiler).

• Of course you don't write whole programs in asm. You write hot loops or functions in asm and call them from C. Modern compilers are fantastic at large-scale optimization, making "brittle" asm that takes advantage of lots of things that happen to be true after inlining / constant-propagation. Doing this around some hand-tuned code (small enough to be updated in future) can give great results. Compilers definitely miss local optimizations sometimes. Often you can use intrinsics to manually vectorize or something, if the missed-optimization was auto-vectorization related, though, not asm. – Peter Cordes Feb 23 '18 at 6:43
• As you point out, actually hand-writing in asm tunes only for current microarchitectures, so in my experience the best thing to do when performance tuning with future-proofing in mind is to read the compiler output, and if the compiler didn't make optimal asm, tweak the source to hand-hold it into finding a more optimal way to compile (See my Collatz conjecture answer on SO). Then you have nice asm with your current compiler for your current hardware. Some future compiler can hopefully make different asm if needed for future hardware. – Peter Cordes Feb 23 '18 at 6:48