21

At some point it became easier and faster to write high level code than assembly. I'm curious about the transition - right now a full time assembly programmer is rare indeed, although there are still some niches for it. Was there an industry upheaval where jobs became obsolete over night? Did a lot of people lose their jobs?

14
  • 45
    Most programmers are happy to learn a new language. It isn't like overnight assembly was "obsolete" and there were a whole bunch of high-level language programmers untainted by assembly magically available. Programmers are programmers.
    – Jon Custer
    Commented Jul 11 at 15:31
  • 8
    This is based on a misconception. Languages of all levels have always been used. There is no such thing as "mainstream"
    – Chenmunka
    Commented Jul 11 at 20:48
  • 19
    Some of the assembly programmers became compiler writers.
    – Erik Eidt
    Commented Jul 11 at 23:08
  • 6
    High-level languages have been around since 1950s (e.g. COBOL 1959), while games were routinely written in assembler well into the 1980s and beyond. The overlap era is huge. In practice, what happened was the market for programmers expanded almost continuously.
    – pjc50
    Commented Jul 12 at 16:09
  • 4
    Programming is programming. In the last decade I haven't touched any language I learned in school. So what? The fundamental skill is "programming", not "8086 assembly" or "basic". It's all effectively dialects to an underlying concept. Commented Jul 12 at 23:35

10 Answers 10

61

This isn't like "what happened to the stable hands when cars replaced horses". It is more like "what happened to the mechanics who worked on manual transmissions when automatic transmissions became more popular" - they learned how to fix automatic transmissions, but they still work on manual transmissions when needed.

Assembly language was constantly changing anyway. Arguably, until the IBM System/360 in 1964, pretty much every significant new system had a new assembly language to learn. By that same time period, FORTRAN and COBOL were well established and many other high-level languages were available or under development.

At some point it became easier and faster to write high level code than assembly.

Arguably that was at the point that the first high-level languages were developed. But "easier and faster to write" was not, and still is not, the only criteria in a programming language. If it was then assembly would have totally disappeared decades ago. There are still situations where assembly has advantages:

  • Smaller code - Less of an issue today but a big deal when 64k (often far less) was a "big" system
  • Fast execution - Compilers keep getting better, but there is almost always room for improvement. As with code size, less of an issue today when clock speeds are measured in Gigahertz instead of Megahertz or even Kilohertz.
  • Low-level access to hardware - With some high-level languages, such as C, low-level access to the hardware is possible. With many other languages it is either tedious (BASIC PEEK/POKE) or impossible due to deliberate safety limitations built in to the language/compiler and/or the operating system.

I have written some assembly (a little bit on mainframes during college, a little bit on Intel x86 since then) but not lately. But if I needed to, I would learn assembly language for whatever CPU is needed for a customer's project. And if I started out doing everything in assembly language then I would have had to learn several new languages by now - either assembly language for new CPUs or high-level languages.

And if you haven't read it already, you have to read Raffzahn's story.

16
  • 9
    Even when writing C, an understanding of the target architecture's instruction set may be useful if one wants to ensure that generated code will neither be severely sub-optimal (worse than what a relatively mindless translator might produce) nor erroneous.
    – supercat
    Commented Jul 11 at 18:03
  • 3
    There's maybe also a very important third point: Library and/or Runtime support. If it's just about using C vs. Assembler, then basic C yields not much of an advantage - once either environment is set up. That little support standard C provides is also available in Assembler. It gets harder once additional libraries and especially frameworks tailored for C usage are involved. Here a start in C may save quite some time - not because of the language, but because of the ready to use environment. Otherwise, if that application specific enviromnmet has to be created first, the race is open again.
    – Raffzahn
    Commented Jul 11 at 18:26
  • 8
    BTW, I LOVE that first paragraph :))
    – Raffzahn
    Commented Jul 11 at 18:27
  • 3
    @Raffzahn It worked the other way, too — I remember being frustrated by a C development system whose library didn't provide bindings for OS calls and functions I needed.
    – gidds
    Commented Jul 11 at 22:42
  • 4
    (Just a comment because I don't have time to write an answer, plus there are 8 already:). Don't underestimate how much simpler things were then: a) those few HLLs usable in production then were very simple by today's standards; and b) "software engineering" didn't exist, no O-O design, no "design patterns", etc. etc.. Those two things plus the fact that assembly language programmers were very close to the machine - much more than today's programmers!! - meant they had a very usable stable model to build on when understanding the simple HLLs of the time.
    – davidbak
    Commented Jul 12 at 15:02
25

I worked through the UK period where assembly programmers moved to C for embedded systems, throughout the 1980's. By and large, our clump of programming engineers quickly knew several assembly languages anyway (Z80, 6502, 6800, 68000, PIC) as we enjoyed learning new languages.

The move into C was gradual. May of us learnt the language though curiousity at scattered times, long before we got the chance to use it professionally. We continued to support the assembly programs while working in C so we worked on both for many years. I also looked into every programming language whose documentation came near me in those pre-internet days and learnt from their ideas (particularly learning C++ and Ada in depth much later).

We were trying to squeeze the maximum performance out of the limited CPU speeds back then, so efficiency was very important. Just churning out wish-list C, without a thought to the assembly instructions those more limited compilers/optimisers produced, would usually make a program too slow and/or too big. You really had to have a solid appreciation of how the CPU would do it to produce decent and worthwhile C programs.

These days, microcontrollers can nearly always have a lot of spare capability compared to the 1980s/1990s parts, for very little extra cost. It depends on your target market as to whether you can afford that extra cost but it's much more attainable now. So programs can be more inefficient and still get their tasks done in time, meaning it's not so essential for programmers to understand the CPU instructions generated by their C program. And compilers/optimisers have evolved in quality substantially.

Some of our team's examples are:

  • In 1990 and in development, two of us used 12 MHz 8752 MCUs (8052, 256 bytes RAM, 8 KB EPROM) at over £20 each (over £65 in 2024).

  • By 1994 and in production, cheapest for us was a 20 MHz 8032 MCU (8052, 256 bytes RAM) with external 32 KB EPROM totalling about £5 (£13 in 2024) for 10,000 parts/year.

Nowadays, it costs far less for an MCU going 32KB->64KB or 32KB-256KB Flash EPROM in same package. The latter would've been something like another £15 (£38 in 2024) for extra external EPROM in volume back in 1994. Such an MCU usually comes with at least 4..8 KB RAM, again far more than our 256 bytes, and has a far faster CPU.

2
  • 14
    C was devised by and for programmers who already knew assembly language. Students who came from a FORTRAN background often found pointers and bit manipulation difficult to grok.
    – John Doty
    Commented Jul 11 at 21:22
  • 3
    @JohnDoty: Unfortunately, the direction of the language is controlled by people who are clueless about what the things that makes the abstraction model used by assembly language useful in the first place.
    – supercat
    Commented Jul 11 at 23:02
21

Great points so far, but one hasn't come up so far:

Most just continued doing Assembly.

After all, the market they served didn't vanish. Not over night nor in long term. This was quite the case in mainframe environments, as those were quite stable up until today. It's the same way as why COBOL still thrives on mainframes. In this setting new Assembly developments, even larger ones, were started as late as 1990. Usually as part of an existing landscape, where continuing in Assembly was simply more effective than going thru the troubles of integrating other languages.


In addition the question may be based on a dual but intervened misconception of

  • programmer jobs being a limited offer as well as
  • High Level Languages being developed to improve existing development

Neither really holds true.

Assembly was all around excepted and regarded well fit. The real case for HLL came due the need for more programmers then there were and could be trained. Both major early Third Generation Languages(*1), FORTRAN and even more COBOL, were developed to allow every user to formalize their programming needs without having to train them as programmers(*2,*3). Fortran by simply writing 'standard' formula and COBOL by using plain English to describe business algorithm. That way every scientist, engineer, clerk and manager would be able to use a computer without needing a programmer turning his requirements into code.

We all know how this worked out: A huge demand for COBOL programmers next

Of course in some way they helped as they allowed user to change trade and becom programmers - after investing many hours (*4). Various powerful similar 3GL languages like (Business) BASIC tried the same for mini and later micro computer, again just creating the need for even more specialized programmers.

The late 70s/early 80s gave us a flood of 4GL, from Informix to ABAP, hyping empower Joe Average without needing to consult/employ programmers ... and failing again the same way.

Do I need to mention today's hype about AI enabling everyone to write needed software on the fly - or at least put real programmers out of ob by learning 'prompt generation'?

The wish to make machines program themself is strong enough to repeat history over and over. Same result every iteration. Plus new languages that were supposed to be the solution.


*1 - Machine code being 1st and Assembler being 2nd.

*2 - The third one, ALGOL and thus all of it's offspring, being an outlier in that theme as ALGOL did not focus on ease of handling but clear and stringent support of basic programming structures.

*3 - Of course there were as well special cases, from APL all the way to FORTH, but they are rather that, developments for very special application cases more DSL than general purpose.

*4 - Many might remember those guys from some department writing some super useful BASIC/Excel/whatsoever tool that had to be linked with the main system by order of management.

6
  • 1
    I daresay you can still find work in this language.
    – Trunk
    Commented Jul 12 at 10:43
  • I know a some assembler programmers who learnt C because it started replacing some of their job or jobs - and often their assembler knowledge remained important, as (especially early) C wasn't really that close in to assembler in performance, and abstractions also leaked. Commented Jul 12 at 15:55
  • Not sure I like to think of machine code as a "language." But, if it must be one, and if it occupies level 1, then I propose; Level 0: microcode, and Level -1: hardware design. Commented Jul 13 at 3:35
  • @SolomonSlow That's simply the definition there is. Also, machine code as 1gl does not necessarily mean binary or hex, but whatever encoding used that the machine could read/store/execute without a translator software. Next, micocode is not a user side language (and introduced only after 1GL). last but not least Hardware design is as well not user side - nor programming at all. Plugboard may make an exception to the rule - albeit a rather far one.
    – Raffzahn
    Commented Jul 13 at 9:55
  • @Trunk parts in IBM z is still (macro)assembler, so yes someone with good (macro)assembler knowledge prepared to train youngers can still find work. Commented Jul 15 at 19:33
20

The question seems to assume that a (good) programmer is either an assembly-level programmer or a high-level language programmer, and that a job description requires one or the other.

This doesn't square with my actual experience. I'm hired to build things. Generally, I get to decide the implementation language, and this decision is not based on my preference, but my analysis of what is appropriate.

It is true that it's been a long time since I (professionally) wrote anything more than a couple of selected routines in assembler, but that doesn't change the nature of the job. A professional programmer is expected to pick up new tools and use them. I laugh at job descriptions that will only hire people who already use particular tools.

10

The whole point of "high-level languages" was that they were supposed to be easier to master and more productive than assembly. So there's no reason to think an already-competent assembly programmer, if he needed to reskill, would struggle to make himself useful in the marketplace.

Also, the "software crisis" has been ongoing since the 1960s, and each passing year draws more people into "programming" or the various trades which are ultimately allied to it.

That is, the general trend has always been toward expansion of the overall workforce, so there's never really been a mass of experienced software people who ended up on the scrapheap despite wanting to work.

Finally, the transition to high-level languages itself was not sudden but took decades, so the whole assembly workforce was never posed at once with a sudden need to retrain. Rather, entry-level jobs in pure assembly shrivelled, and it became harder for the oldest workers with assembly-only experience to battle on after an employer-specific redundancy and stay in the market without opting to retire, much as has become the case with COBOL.

Arguably what caused this gradualism is that even when high-level languages became available, the largest and most experienced workforce available were still those who knew assembly and whose training cost was already sunk.

So if you were starting a big new development and wanted a chance of it getting done, the choice is not freely between languages, it is between (a) the most widely available workforce (including software managers) with solid experience of assembly-based development, and (b) a narrower workforce consisting of older hands choosing to dabble with newer languages and compilers less familiar to them, together with the younger and less experienced. It takes quite a number of years after a specific language becomes available, before this labour market balance changes.

Other reasons for a long transition time include that there was a significant amount of installed assembly code that still had to be maintained and interfaced with, and that there were enough special cases where assembly exceeded the performance, reliability, or all-round usability of high-level languages and compilers that assembly continued to be used preferentially for new development for many years.

7
  • Assembler and high level languages require different skills to master; a master assembler programmer can probably become a journeyman high level language programmer with ease, and vice versa, but it isn't as if one is strictly harder than the other. High level languages are assembly generators, and you can generate geometrically more code than you can write: at the extreme, it is like the difference between a woodworker and someone operating a machine that makes chairs, or even a machine that makes machines that make chairs. Commented Jul 12 at 15:58
  • 1
    @Yakk-AdamNevraumont, there's some kind of learning curve, but it's still essentially data structures and algorithms. The jump from assembly to C is less like carpentry versus machine design, much more like hand tools versus power tools. You wouldn't expect a skilled hand carpenter, to struggle with the idea of using power tools.
    – Steve
    Commented Jul 12 at 16:51
  • Sure, so you get to journeyman for nearly free. My standards of mastery are high. Commented Jul 13 at 15:38
  • @Yakk-AdamNevraumont, in that era, the vast majority of programs were not written off the cuff, but typically went through extensive top-down design on paper (diagrams, flow charts, structured English). The main mastery in assembly was ekeing out every last bit of performance, and most of the basic structure of the program was already set by time any actual computer code came to be written. Moving the last step from assembly to say C, was a labour-saving and de-skilling event that still used most of the existing design methods, not really something that required even more mastery. (1/3)
    – Steve
    Commented Jul 13 at 20:01
  • 1
    By time later HLL compilers actually were better than assembly programmers at optimisation, assembly had already fallen into disuse because in the meantime it had become technologically feasible to put up with slower, bulkier programs written in HLLs (and compiled with earlier, poorly-optimising compilers)! Whereas the inefficiency of HLL compilers had previously been intolerable during the heyday of assembly use, regardless of the human labour savings. (3/3)
    – Steve
    Commented Jul 13 at 20:06
8

I wrote the memory manager for a mainframe in assembler.

Then I wrote VB applications, and they were soaring and magnificent and beautiful. I wrote 3D graphics for the nuclear industry that nobody ever did on the PC. I could NEVER have done it in assembler.

Before that, I was just a coder of data structures. But at the nuc place, the guys were all engineers, not programmers. I did these quick one off jobs that took almost no time (months) and made us huge money.

With all those VB system functions, I could add dozens of little irrelevant presentation details that made the program just SO much slicker and professional. Freed from assembly language, I won awards and was the company hacker elite.

And once hack, never back.

8

I once wrote a device driver on the VAX/VMS operating system.

This was after mainstream programming had transitioned to high level languages. However, systems programming hadn't. The VMS operating system was (probably still is) mostly written in a special purpose language invented by the DEC (the manufacturer. I cannot recall the name of this language but it was somewhat lower-level than C). Drivers, however, were written in assembly.

Assembler really isn't that hard to pick up. The hard part is coding in an environment where absolutely any error is fatally bad. If you are lucky it crashed the system as soon as you loaded and used it. If you were unlucky it caused corruption that crashed the system seconds/minutes/days later!

So I expect the answer is that good assembly programmers became systems internals programmers, and less good ones learned a high-level language.

A third possibility is that they kept moving on "downhill" to smaller systems that didn't have C compilers. Programming TV remote controllers or keyboards with soft buttons. Or even, these days, flashlights. A colleague once moved on from PDP11 minicomputers to those newfangled microprocessors. Keep on to today, you have things like a PIC10F200, with 256 words of EPROM program storage and all of 16 bytes of RAM. I expect this is just about enough to program a flashlight to do Bright / Dim / Flashing / Off, but not using C. (link to PIC series data sheet). These six- and eight-legged beasties cost mere pennies today.

I will probably find a reason to tinker with such things in my retirement.

2
  • 5
    en.wikipedia.org/wiki/BLISS may be the language you're thinking of.
    – LAK
    Commented Jul 12 at 13:33
  • 3
    Early VMS was mostly written in VAX MACRO (basically VAX assembly) and as @LAK mentioned some in BLISS.
    – Andy C
    Commented Jul 12 at 13:39
8

I think one thing that is missing from the answers and discussion is the exponential growth that occurred throughout this time.

When assembly was the only option, being a programmer wasn't really a separate role. Everyone who maintained, worked with, or used a computer had to program it -- there wasn't any choice.

While some systems programs were ported from assembly to C (and other languages), the introduction of FORTRAN, COBOL, C (and other languages) also served to vastly increase the number of people who could write programs and the kinds of programs that could reasonably be developed.

At the same time, more and more computers were being developed, sold, deployed, and used.

If you're in something before a phase of explosive growth, you don't lose your job because of that growth. For you, adopting C or FORTRAN or continuing to develop in assembly is as natural as it comes -- and there is constantly increasing demand for your skills.

3
  • This seems to compress C and FORTRAN into the same sort of time period. They were at least 16 years apart (more by the time C escaped Unix).
    – dave
    Commented Jul 13 at 2:26
  • @dave Fair point, but now that we're some 70 years after the creation of FORTRAN, that does seem a bit the same era (at least to the kids these days). Most of the languages from that time did not survive, I kept my comment to those that did. FORTRAN and COBOL were notable because they targeted specific applications beyond simply making a computer work -- they are languages developed specifically to expand the use of computing. C is notable because it took over as the de facto systems programming language that replaced assembly in all by the niche areas where we still use it today. Commented Jul 13 at 6:05
  • @RobMcDonald: Regrettably, the Standard never recognized that the goal of C should be to behave in a manner consistent with a high-level assembler in all ways and cases that matter, and that there should be a means by which programmers can indicate which aspects of execution do matter.
    – supercat
    Commented Aug 6 at 17:50
5

When programming in C, it's often useful to have an understanding of the target platform's machine architecture, and be able to judge whether the compiler is processing one's code in a manner that is reasonably efficient and that will satisfy application requirements. Code-generation bugs in commercial compilers are rare, but they can happen, and have symptoms that would be impossible to diagnose without examining the generated code. For example, in the 1990s I worked with a compiler for the 68000 series that would sometimes mis-adjust the stack pointer by 65,536 in a manner that wouldn't affect the behavior of the erroneous function, but would disrupt its caller's stack frame. Someone who didn't understand 68000 assembly language would have had no hope of finding that problem.

While maintainers of free compilers would insist that the Standard allows them to process code in "interesting" ways, I doubt anyone who couldn't read ARM-Cortex M0 assembly code would be able to figure out how a function like:

uint16_t test(uint16_t *p)
{
  uint16_t temp = *p;
  return temp - (temp >> 15);
}

could return 65535, even if some outside process changed the value of *p during its execution.

14
  • Yep. I've never written any 68k assembly, but I've read many a line of it, debugging, or trying to coax the C optimizer to make it efficient.
    – John Doty
    Commented Jul 12 at 16:53
  • @JohnDoty: Can you imagine how a compiler given the latter function could produce code that would behave as described? The ARM Cortex-M0 is a 32-bit processor which supports 16-bit stores (sign agnostic) as well as signed and unsigned 16-bit loads.
    – supercat
    Commented Jul 12 at 18:06
  • 1
    My reaction to that code is that the 'even if some outside process changed the value of *p' part cannot be guaranteed in the absence of volatile. Am I wrong?
    – dave
    Commented Jul 13 at 12:58
  • 1
    @supercat - right, the C language permits *p to be read twice. Which is why that code fragment is wrong. On second read, maybe that's what you meant all along.
    – dave
    Commented Jul 13 at 20:50
  • 1
    @supercat I'm not sure what your point is with the example. Are you just trying to say that compiler bugs (which this is) are hard to diagnose without knowledge of the architecture's assembly language. This is trivially true.
    – JeremyP
    Commented Jul 15 at 13:20
3

Assembler coding is no longer relevant for developing new applications on mainstream computer systems, but there are lots of niches where it is still used:

  • Really small embedded systems.
  • Internals of larger systems: the lowest level of bootstrapping, the lowest level of math libraries, the lowest level of operating systems, sometimes device drivers, sometimes bindings for calling operating system functions from higher level languages, and many more.
  • Maintaining legacy systems written when assembler was more mainstream: lots of IBM mainframe stuff, some other old mainframes, and the like.
  • Anything that has to run fast benefits from knowing assembly language: I optimised a critical compare routine to its limits by writing C, reading the generated assembler, benchmarking and revising.
  • If you're working with newly developed platforms, you'll hit compiler bugs, and being able to read and debug the assembly language makes your bug reports much more useful.

There are more uses: those are just the commoner ones. Being able to learn and use a new assembly language quickly lets you solve problems that are too hard for many developers.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .