Search code examples
gccarminline-assembly

How can I create an Inline assembly command with a multi-variable register offset?


The following code, using gcc for ARMv4, is perfectly fine:

asm("strb.w r2, [r0, #24 + 8 * 1]");

Now, if I try the following:

asm("strb.w r2, [r0, %[offset] + %[delta] * %[scale]]"
    :: [offset] "i" (24), [delta] "i" (8), [scale] "i" (1)
);

I get

strb.w r2, [r0, #24 + #8 * #1]

which clearly is wrong. How can I accomplish this?

asm("strb.w r2, [r0, #24 + 8 * 1]");

Solution

  • Turning the comment into an answer since it seems to work:

    Looking at the gcc docs for inline asm, we see there is a modifier that can be used for "i". Adding c will:

    Require a constant operand and print the constant expression with no punctuation.

    So changing your code to something like this should give you what you want:

    asm("strb.w r2, [r0, %[offset] + %c[delta] * %c[scale]]"
        :: [offset] "i" (24), [delta] "i" (8), [scale] "i" (1)
    );
    

    BTW: While this may give you what you're after, as a general rule I recommend that you don't use inline asm (despite how powerful and cool it is). Obviously I don't know your specific requirements, but there are good reasons to avoid inline asm when possible.