Assembly Language and Embedded Systems Development

On the Value of Assembly Language, and Resources to get you started in Digital Logic, Computer Architecture, and Assembly Language programming.

Despite advances in programming technologies since the 1970s, there are still reasons to understand and learn assembly language programming. Contrary to what one may imagine, Assembly Language is not a relic of the past, even though a typical applications programmer will almost never need to drop into assembly.

In this article, we’ll look at practical situations in embedded systems development in which assembly language programming is still used, pedagogical reasons to learn assembly language, and provide resources and projects for gaining a working knowledge of digital logic, computer architecture, and assembly language programming.

Learning for Embedded Systems Development

Despite advances in programming technologies since the 1970s, there are still reasons to understand and learn assembly language programming. Contrary to what one may imagine, Assembly Language is not a relic of the past, even though a typical applications programmer will almost never need to drop into assembly. Certainly assembly language is NOT recommended for writing general applications software or graphical user interfaces. Yet a decent understanding of assembly language is important both practically in embedded systems development, as well as for developing a solid general understanding of computer engineering, the underpinnings of the software development toolchain (compilers, assemblers, linkers, loaders, debuggers, and so on), and in the analysis and implementation of algorithms.1

The transition to embedded systems development is difficult without a reasonable understanding of assembly language and computer architecture. As embedded computing enters almost every aspect of the modern technology landscape, from intelligent gadgets of all kinds to remote and autonomous systems, not having this knowledge becomes a fundamental impediment to seeing and being able to seize the many opportunities for participating in this interesting and rapidly expanding area.

(I.) Practical reasons for understanding Assembly Language programming
There are at least four practical situations in embedded systems development, in which assembly language programming cannot always be entirely avoided:

  1. when developing for platforms that do not have C compilers — and these do exist — assembly language becomes, in most cases, the programming interface. The popular Microchip PIC microcontrollers used to be without a targeting C compiler for many years, in part because of the idiosyncratic PIC architecture and the absence of facilities (like a deeply nestable parameter stack) that general compilers require. With their low cost (many under $3.00) and extensive array of built-in peripherals, incorporating these powerful microcontrollers was often done using assembly language programming.2
  2. when systems require hard real-time performance in the absence of a real-time operating system (RTOS), assembly language on a RISC platform allows interacting directly with the silicon and being able to obtain accurate timing characteristics by counting instructions. This is one of the advantages of the RISC (reduced instruction set computing) architecture — it is a simplified architecture in which each instruction takes a fixed and uniform time for the CPU to execute.
  3. when writing device drivers or obtaining peripheral access in the absence of an operating system that provides this functionality, or when writing drivers for an operating system.
  4. when it is required to directly supervise the storage of values to specific registers or the use of specific elements of an underlying CPU architecture, C is often unable to help. Being able to drop into assembly, either inline or through functions, is then the most direct method of access.

This is not to say that the disadvantages of assembly language programming are any the less — assembly language is not portable and almost always has higher overhead when coding, debugging, and maintaining. But in these few areas of embedded systems development, the benefits occasionally outweigh the trade-offs.

It should also be clear that none of these four conditions is ordinarily encountered by a typical applications software engineer. Indeed, these conditions do not always arise in embedded systems development either, especially if the embedded development is done atop an OS or RTOS sitting on a computing platform for which there is a quality C compiler.

So the question remains: for the large number of programmers and engineers for whom the practical reasons are unlikely to materialize, is it useful to learn an assembly language?

(II.) Pedagogical advantages of learning assembly language

Programming in Assembly Language requires a non-trivial understanding of the innards of digital systems and software toolsets. It provides a fruitful hands-on context within which to acquire and exercise this understanding. Compared to higher level languages, assembly language programming requires greater understanding of the following:

  • digital logic and digital circuit concepts
  • computer architecture: register, bus, memory, the instruction cycle
  • microprocessor organization: opcodes, characteristics (timing, organization, peripherals)
  • hexadecimal, binary, and decimal numbers and how to use them
  • stack
  • memory access and pointers
  • assembler syntax: pseudo ops, directives, syntax, number formats
  • calling conventions
  • operating system facilities
  • the parts of a software toolchain
  • linkers and their idiosyncrasies
  • loaders, when loading the binary program into memory on a target platform that isn’t the source platform
  • using a low-level debugger

Grappling with assembly language programming gives a much better understanding of computing architectures. Once you understand digital circuits and computer architectures, assembly language programming and its toolchain, you will have the working knowledge needed to embark on the road to microcontroller programming and the development of small and medium scale embedded systems applications: reading in sensors (A/D, filters, signal processing), digital I/O, and real-time numerical methods. 3 In addition, the patterns of thought involved in thinking in assembly, and the discipline involved in writing readable code in assembly, are both invaluable in understanding the details that a higher-level optimizing compiler handles “under the hood”.

Recommendations and Learning Resources

The best way to gain a working understanding in the areas discussed above is to do some digital logic design and assembly language coding yourself. The tools are not difficult to acquire and the materials to begin are available for free.

For digital logic and computer architecture, the Digital Works simulator is a simple, freely available, and user-friendly way to get started in digital logic and computer architecture. [Download from Resources]

It is helpful when embarking on learning ventures to identify a defining project that is grand enough to whet your ambitions but is also chosen to guide your learning efficiently through the essential areas you’ll need in order to have a strong working knowledge.

Project (Digital Logic and Computer Architecture)

Design an ALU in hardware to form the heart of a simple calculator. Build up the necessary logic elements using your own ICs that you package up in Digital Logic to be pin-compatible with ICs that you might buy off the shelf.

Excellent IC lists with pinouts are available from GIICM. Datasheets and practical issues like availability and alternatives are available through the DigiKey parameterized product selection index. [See Resources for links].

For assembly language programming, the x86 is an adequate platform for learning the basic techniques, including how to extend assembly language with higher level calls, how to embed assembly language directly into higher level languages, and using all the elements of the software development toolchain: compile, assembler, linker, loader, debugger.

A companion project to the digital logic project above is given below:

Project (Assembly Language)

Develop, in assembly language, computational routines for a simple calculator, including fixed and floating point routines and some basic vector operations (sum, difference, and scalar product).

After getting your feet wet in pure assembly, the way to go here is to migrate into C or Basic (gcc or FreeBasic are two recommended open source packages) and learn how to embed assembly language into higher level languages.

MicroASM is a simple, freely available, and user-friendly way to get started with assembly language programming, after which migrating to NASM, gas, gcc, and the other elements of an open source toolchain is next. [Download from Resources]

Next steps

Once this understanding has been obtained, assembly should be viewed as a tool to use when it is practically needed. In all other cases when a C compiler exists that targets your intended platform, you should be writing in C. Optimized compiler technology has become so good that it is better to let a computer do what it is better at: detailed automatic attention to the placement and organization of assembly code, while your creativity directs the implementation via a higher level language (C or higher).

Two directions then open themselves, one taking the road into computer science: assemblers, compilers, parsers, and higher level languages, and the other taking the road into microcontrollers, sensors, and embedded development.

Stay tuned!

Related Reading and Resources

Related Reading

Downloads & Resources

Digital Logic & Computer Architecture

Assembly Language for x86

  • Download MicroASM v1.00 (freeware) an 8086 assembly language platform and 8086 visual emulator for beginners to learn assembly language concepts and programming. Note: requires VB6 runtimes, which can be obtained from Microsoft here.
  • Download MicroASM v4.08 (shareware)
  • x86-assembly-toolsetAn Open Source Assembly Language Toolset contains a discussion of an intermediate level Open Sources assembly language toolset for the x86


    1. Using Assembly Language for Algorithm Analysis

      This is what Knuth does in The Art of Computer Programming, a Tour de Force in the detailed analysis of fundamental problems and methods in computer science, their techniques and complexity analysis. For these analyses, Knuth assumes an ideal machine, MIX (for the 1960s) and MMIX (for the 2000’s) – a RISC style computer. He abstracts away specific details that aren’t relevant to the essence of algorithm complexity — i.e. the number of registers etc.

      It is often useful and helpful to taste implementing an algorithm in assembly language. For this to be practical, you need the facilities of disk access, data loading and saving, and display. These are most practically handled by the OS on a modern CPU, so it is easiest to use the OS functionality. It is also easiest to do all of this within a higher level language in which this interaction is usually quite easy. So the best way to proceed is by embedding (inlining) your assembly language implementations within a higher level language such as C/C++ or Basic.

    2. Microchip PIC18 and dsPIC, Atmel AVR, and Intel 8051 are all families of microcontrollers that have reasonable optimizing compilers available today, a large and helpful user community, and easy pathways to entry level embedded systems projects.
    3. When you are ready, an inexpensive, RISC based, non-x86 platform for experimentation becomes handy. Microchip PIC, Atmel AVR, and Intel 8051 are all widely used microcontroller platforms worth considering.
  • Leave a Reply




    Your comments are valued! (Please indulge the gatekeeping question as spam-bots cannot (yet) do simple arithmetic...) - required

    You can use these HTML tags

    <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

    Dear Readers!

    Our Google+ (Buzz) page is where we publish more regular (~monthly), shorter posts. Feel free to check it out! Full length articles will continue to be published here, with notifications through the Feed (you can join the list below).