Editor's Note: See also Part 2 of this two-part article.
While studying for my degree way back in the mists if time, I was out on placement at a research facility sometime circa 1978. One of my tasks was to create an image processing algorithm that could take the output from a digital camera (as I recall, it was a "diode-array" camera with a resolution of only 64 × 64 pixels) and isolate and identify raised numbers on the bottom of glass bottles rolling down a conveyer belt.
This was a somewhat interesting problem, because the bottles – which were illuminated by two light sources mounted underneath the conveyer belt at 90° to each other – could be in any rotational orientation. This meant that different facets of the glass "bumps" forming the numbers could be illuminated from one bottle to the next (of course the bottles could also be spinning, but I only took a single "snapshot" image for each bottle and then processed this static representation).
My task was made more interesting in that I had to create the program in assembly language for the TI 9000. In addition to being the first microcomputer I'd ever seen, this was also the first time I'd ever been exposed to assembly language (the guy who had ordered the microcomputer had left the company before it arrived, so I was given the manuals and instructed to learn it myself). That's when I caught the bug, and I've loved playing with assembly language ever since.
The results are in. . .
Odd ideas are popping in and out of my head all the time, and every now and then I share my ponderings with the readers of Programmable Logic DesignLine. A few weeks ago, for example, I was speculating about the use of assembly language. After chatting to a variety of different people one day, I gained the impression that the world is split between "application-level-type" programmers (who wouldn't know an assembly language routine if it crawled up their trouser leg and bit them in an unfortunate place) and "embedded-systems-type" programmers (who would).
Actually, in the not-so-distant past when I was a young engineer (well, maybe that is in the distant past now), application-level-programmers were well-versed in both assembly code and higher-level languages like C. By comparison, although we all know what assembly code is, relatively few of the younger application-level-programmers seem to have actually used it in anger; instead they focus on high-level programming languages like C/C++ and scripting languages like VBScript and Python.
In fact, when I ask about using assembly language, many of these folks screw their noses up as though they had just smelled something unpleasant. The overall impression is that working at the assembly level is cumbersome, error-prone, time-consuming, and – generally speaking and in the vernacular of engineers – a "pain in the rear end" to use. Well, yes, I suppose so, but it can also offer advantages, because you are down in the inner machinations of the machine where you can control what happens in exquisite (sometimes excruciating) detail.
So I decided to query the readers of Programmable Logic DesignLine as to their thoughts on this matter. Prior to performing my survey, my own thoughts with regards to the pros, cons, and reasons for using assembly language were as follows:
- You can hand-craft code that's really fast.
- You can hand-craft code that consumes relatively little memory.
- You have total control over what's going on.
- Creating assembly code is time-consuming.
- Creating assembly code is error-prone.
Who/Why Use Assembly?
There are several reasons for knowing and/or using assembly language as follows:
- Folks writing code for Digital Signal Processors (DSPs) often start off capturing the algorithms in C; then they profile the application to determine any "hot-spots" that need "tweaking" in terms of performance-power-timing and recode these portions of the code in assembly.
- Low-level drivers or other embedded applications that require the ultimate in performance may contain portions written in assembly language.
- You may be maintaining an old "legacy" application that contains functions written in assembly language.
- You are creating a compiler that takes a high-level language and translates it into assembly that will subsequently be translated into machine code. In this case you aren't writing the assembly language, but you do have to have an intimate understanding of it.
- You are reverse-engineering an application (doubtless for totally legal reasons) for which you do not have access to the source code.
- You are forced to learn it in one of your college courses.
Well, you can only imagine my surprise, because as soon as I'd posted my survey, the floodgates opened and emails started winging their way across the Internet from all corners of the globe. As you might expect, the responses ranged across the board, from those who were passionate advocates for the use of assembly language to those who loathed it with a passion. A typical response was as follows:
I'm currently working on three software projects that are assembly language based. The reason I'm steered toward assembly language is simple. The chips involved are 8051-based chips with 1 KB of code space. These parts are cheap, but they have limited code space. Assembly language is the best approach for getting our money's worth out of these chips.
Some responses included some very useful points to ponder; for example:
In my experience, potential pitfalls of assembler are:
- Bugs due to lack of rigor in register allocation and use.
- Bugs due to problems with register & memory scope as routines are called.
- Bank switching issues during call/return across page boundaries.
- Low level instruction ordering mistakes/violations with modern RISC processors.
And there were lots of thoughts that I'd never even considered. For example, one respondent noted that a big advantage of assembly language to his mind was that if there was a problem you tended to discover it really quickly because the system typically "crashed-and-burned" in a very obvious manner. By comparison, he commented, problems in higher-level language code tend to manifest themselves in a less forthright way (grin).
Having said this, another respondent had an opposing point of view, because he noted that in his experience there were far more long-term bugs in assembly language projects (that is bugs that only came to light several months after the code was released) than in C-based projects.
In fact, there were so many different viewpoints and interesting considerations with regard to the use of assembly language – including some folks who were both for and against at the same time – that I decided to simply abstract and condense their responses as follows:
In the distant past when I was a young engineer, everything was written in assembly language. Some of my first projects involved writing avionics code for both commercial and military applications, and it was non-trivial stuff amounting to thousands of lines of code. Debugging with a logic analyzer let me know exactly what was going on, bus cycle by bus cycle, and that level of insight and control is what I loved about assembly language. And once I'd built up a good library of subroutines, coding seemed to zip right along.
Fast forwarding to the present, if there's a good compiler available I try to do my embedded stuff in C. On the desktop I'm in the process of switching from C to Python. Yet just the other day I turned on the assembly listing switch in my compiler to verify an addressing problem involving an un-initialized pointer, and the assembly code showed the problem clearly.
The desktop crowd may regard assembly as an anachronism, but in the embedded world it's still a very useful tool.
Your article sums things up pretty well. When I first got a job in the company I'm now software manager at, I got put on a project written in NEC 4-bit assembler. I spent four years on that project, and although assembly language programming can be fun – sometimes – I wouldn't describe that experience as particularly enthralling, certainly not after the first week anyway!
All our products are now written in C or C++. Occasionally I do use assembly language, for example to make an SPI driver go as fast as possible, and once because my compiler refused to use the DIV instruction in the microcontroller for some reason. I once worked at a place where the software manager insisted that you could NEVER use assembly language, because it made the code non-portable. He failed to see that often the reason that assembly language is used is in an area where if it was written in C it wouldn't work anyway – tight or exact timing requirements etc. I would never ban any of my guys from using it; I rely on their common sense!
My experience is that there were far more long-term bugs in the assembly language project (that is bugs that only came to light several months after the code was released) than in any of the 'C' projects since then.