Home > Net >  arm inline assembly - store C variable in arm register
arm inline assembly - store C variable in arm register

Time:05-12

Trying to save a variable in an arm register using inline assembly.

    unsigned int lma_offset = 0x1234; // typically calculated, hardcoded for example

    __asm volatile ("MOV R10, %[input]"
        : [input] "=r" (lma_offset)
      );

This changes lma_offset to 0xd100 in my case, instead of setting the register. What am I doing wrong?

PS: when I declare lma_offset as const it gives a compiler error because lma_offset is used as output. So obviously something is wrong, still I cant find the correct syntax for this.

CodePudding user response:

For future reference, according to Erics comment

const unsigned int lma_offset = 0x10000;

__asm__ volatile ("MOV R10, %[input]"
    : // no C variable outputs
    : [input] "r" (lma_offset)
    : "R10"      // tell the compiler R10 is modified
      );

using double : and replacing the "=r" with "r" indeed solves the problem.

It would also be possible to ask the compiler to have that constant already in R10 for an asm statement, by using a register local variable to force the "r" input to pick r10. (Then we can omit the redundant mov r10, r10).

 register unsigned r10 __asm__("r10") = lma_offset;  // picks r10 for "r" constraints, no other *guaranteed* effects
 __asm__ volatile ("@ inline asm went here"  // empty template, actually just a comment you can see if looking at the compiler's asm output
   : // no C variable outputs
   : [input] "r" (lma_offset)
   : // no clobbers needed
 );

When writing a register to some output C variable it would result in

unsigned int lma_offset = 0x0;

__asm__ volatile ("MOV %[output], R11"
    : [output] "=r" (lma_offset)
    // no clobbers needed; reading a register doesn't step on the compiler's toes
      );
  • Related