0

Following this manual I wanted to create simplest inline AVR assembly snippet possible: copy values of two variables to two other variables.

uint8_t a, b, c, d;
a = 42;
b = 11;
asm(
    "mov %0, %2\n\t"
    "mov %1, %3\n\t"
    : "=r" (c), "=r" (d)
    : "r" (a), "r" (b)
);

I would expect it to be equivalent to:

uint8_t a, b, c, d;
a = 42;
b = 11;
c = a;
d = b;

However, after running both values of c and d are equal to 42. If I change the asm snipptet to:

asm(
    "mov %0, %3\n\t"
    "mov %1, %2\n\t"
    : "=r" (c), "=r" (d)
    : "r" (a), "r" (b)
);

c is equal to 11 and d is equal to 42 as expected. Similarly, changing both source operands to %2 yields two 42 and setting both of them to %3 yields two 11.

Why the first version does not work as intended?

Pan Hania
  • 456
  • 4
  • 11
  • This question would be better with an [MCVE](http://stackoverflow.com/help/mcve) and the exact command line used to compile the code. – user3386109 Jan 26 '15 at 23:14
  • 1
    Presumably the compiler allocated an input overlapping with an output. You should mark the outputs as early-clobber (ie. `"=&r"`). Also, you should examine the generated assembly code when in doubt (use `gcc -S`). See also [this question](http://stackoverflow.com/questions/26567746/unexpected-gcc-inline-asm-behaviour-clobbered-variable-overwritten). – Jester Jan 26 '15 at 23:19
  • 2
    It looks like Jester has correctly identified the most likely cause of your problem (especially by encouraging you to get used to using -S). But let me offer an educational alternative: `asm("" : "=r" (c), "=r" (d) : "0" (a), "1" (b));`. The way this works is that "0" means that this parameter goes in the same place as parameter #0 (likewise for "1"). So, on input, the first register will contain (a), and on output it will contain (c). Since that's already exactly what you want, no additional asm is required. Cool, eh? – David Wohlferd Jan 27 '15 at 00:36
  • @user3386109 Well, I was actually using Arduino IDE to compile the code so it would be quite bloated and hard to reproduce anyway for someone who does not have Arduino libraries. I guess I have to get friendly with AVR command line tools, especially after @Jester advice. And yes, lack of `=&r` was the problem, thanks. – Pan Hania Jan 27 '15 at 17:40

0 Answers0