Search code examples
carminline-assemblycpu-registers

ARM inline assembly, registers are read in an incorrect order


I am trying to read ARM registers via C using inline assembly but it doesn't follow the order of execution as it should.

volatile uint32_t var1 = 0;
volatile uint32_t var2 = 0;
volatile uint32_t var3 = 0;
volatile uint32_t var4 = 0;

__asm volatile(
    "mov r0, #5\n\t"
    "mov r1, #6\n\t"
    "mov r2, #7\n\t"
    "mov r3, #8\n\t"
            
    "mov %0, r0\n\t" 
    "mov %0, r1\n\t"
    "mov %0, r2\n\t" 
    "mov %0, r3\n\t"
            
    : "=r" (var1),
    "=r" (var2),
    "=r" (var3),
    "=r" (var4));

What happens is that the output is;

var1 = 8
var2 = 5
var3 = 6
var4 = 7

What I expect is;

var1 = 5
var2 = 6
var3 = 7
var4 = 8

It seems r0 is read last and it starts with r1. Why is that happening?

Note: Ignore the purpose of the code or how variables are defined, it's a copy/paste from a bigger application. It's just this specific register behavior in question.


Solution

  • The arguments passed into the inline assembly need to be incremented;

    "mov %0, r0\n\t" 
    "mov %1, r1\n\t"
    "mov %2, r2\n\t" 
    "mov %3, r3\n\t"