Search code examples
assemblymacrosarm64gnu-assembler

Breaking long macro argument list in GNU assembler for AArch64


I'm writing assembly code targeting ARMv8 (AArch64) in GNU assembler. Not sure if it matters, but I'm coding directly in my ARMv8 target (a Raspberry Pi board) running Linux.

I have a macro with a very long argument list (as in, over 60 arguments) -- I know, this is just wrong, please don't shoot me.

For readability, I'd like to break this argument list over multiple lines, i.e. something like this:

.macro my_macro arg1, arg2, arg3, arg4,
                arg5, arg6, arg7, arg8,
                // ...
                arg61, arg62, arg63, arg64

    // macro code goes here

.endm

I'd also like to do the same when instantiating the macro.

Unfortunately, as soon as I try to insert a line break in the macro declaration, I get the following error:

test.s: Assembler messages:
test.s:123: Error: Bad parameter list for macro `my_macro'

As for inserting a line break in the macro instantiation, although I don't directly receive an error, the code doesn't assemble because all parameters after the line break are ignored, i.e. as though I had instantiated the macro with fewer parameters than it expects, so the missing ones default to an empty string.

According to the manual:

The ‘;’ character can be used instead of a newline to separate statements.

I tried to add a ; to the end of each line, i.e.:

.macro my_macro arg1, arg2, arg3, arg4, ;
                arg5, arg6, arg7, arg8, ;
                // ...
                arg61, arg62, arg63, arg64

    // macro code goes here

.endm

This made no difference. Same thing for a line break in the macro instantiation. I also tried other characters, such as #, @ and // with no luck.

So: is it possible to insert line breaks in the middle of the argument list in a macro declaration or instantiation?


Solution

  • I don't know a way to do this in the assembler itself. However, a common practice when writing Unix-style assembly is to run your source through the C preprocessor before passing it on to the assembler. It's common enough that the gcc command will do it for you if you give your source file a name ending in .S with an upper case S.

    The C preprocessor does support backslash line continuation, so in that case you can write

    .macro my_macro arg1, arg2, arg3, arg4,     \
                    arg5, arg6, arg7, arg8,     \
                    // ...
                    arg61, arg62, arg63, arg64  
    
        // macro code goes here
    .endm
    

    and the whole .macro directive will be seen as a single line by the assembler.

    Having the C preprocessor also gives you the ability to use C-style macros with #define, in case that is useful.