Macro Assembly For AVR Chips


Here’s an interesting tip that can help improve your ability to write assembly code. In an effort to remove the complexity of assembly code for an AVR project [Quinn Dunki] figured out how to use macros when writing AVR code with the GNU toolchain. Anyone using AVR-GCC should keep this in mind if they ever want or need to pound out a project in assembly language.

If you look at the code snippet above you’ll see two commands that are obviously not assembly; PulseVRAMWrite and DisableVRAMWrite. These are macros that direct the assembler to roll in a hunk of code. But avr-as, the assembler used with this toolchain, lacks the ability to handle macros. That’s too bad because we agree with [Quinn] that these macros make the code easier to read and greatly reduce the probability of error from a typo since the code in the macro will be used repeatedly.

The answer is to alter the makefile to use GNU M4. We hadn’t heard of it, but sure enough it’s already installed on our Linux Mint system (“man m4” for more info). It’s a robust macro processor that swaps out all of her macros based on a separate file which defines them. The result is an assembly file that will play nicely with avr-as.

Her implementation is to help in development of the GPU for her Veronica computer project.

20 thoughts on “Macro Assembly For AVR Chips

        1. Yeah, using the standard UNIX macro preprocessor from the 70s to do what it’s meant to do is clearly ignoring the past and repeating it. You could say that the edasm on apple2 was ignoring the UNIX history if it bundled macro preprocessing to the assembler, instead of having bits of modular tools.

  1. I’m pretty sure that the gnu assembler (avr-as in this case) has its own macro capability, although apparently seldom used and not very well documented. here’s a top-level view:

    Assembler macros have several “standard” features, even across multiple assemblers from multiple vendors (MASM x86 macros are “sort of” like Microchip PIC macros, etc.), and are usually more powerful than C preprocessor macros, though they can have other limitations. m4 is very powerful, but very obscure and unlike anything else.

    1. It does, and it’s more than enough for the kind of macros used in the linked blog post. Figuring out the correct syntax for things like local variables is a bit challenging due to the poor documentation, but nothing Google can’t fix.

      1. For what it’s worth, M4 is what autoconf configure files are written in.

        I am not going to complain when someone has not heard of it before, because as best I can tell it is a thing humanity was not meant to know, and they are still among the lucky ones.

  2. As others have mentioned, assemblers typically have their own macro functionalities; there’s no need to bring in a separate preprocessing language. (Though it’s fine if you want to do it; I’m not denigrating Quinn’s work!)

    An entertaining classic in the field is _Object-Oriented Assembly Language_, by Len Dorfman. Used copies are cheap, and it’s an entertaining read. I particularly recommend it for fans of object-oriented programming — or, really, for their friends, who will then be entertained by listening to their anguished cries and watching their descent into madness. But the actual use of assembly macros in the book seems reasonably solid, and it clearly makes the point that the limitation is what you should do with them, not what you can.

  3. you could develop a symbol translator and source builder inside a day to take care of every problem mentioned here…

    AVR and GCC are easy, try working with discreet RISC ICs with no toolchain or documentation…

    1. using even a bash script you can write a more powerful solution in minutes that allows inline symbol tables and replacement…

      I’ve never worked with AVR but I do know it’s one of the most supported vendors out there and this late in the game this stuff is only an issue to new devs who haven’t researched…

  4. Hi folks,

    I use avr-as for a number of modules in FIGnition’s firmware and they use macros quite happily. Take a look at AsmSramMacros.h in the FIGnition GitHub repository (copied here:

    .macro VMSeqReadRam dst addrHi addrLo
    VMUpdateAddrCache \addrHi \addrLo
    VMSeqWaitRam \dst
    in \dst,SPDR
    out SPDR,\dst ;start off a new read.


Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.