Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVR inline assembly: registers to variables?

I'm currently trying to write some code that checks the value of SRAM at a certain address, and then executes some C code if it matches. This is running on an atmega32u4 AVR chip. Here is what I have so far:

volatile char a = 0;

void setup(){
}

void loop(){
asm(
"LDI r16,77\n"        //load value 77 into r16
"STS 0x0160,r16\n"     //copy r16 value into RAM location 0x0160   
"LDS r17,0x0160\n"     //copy value of RAM location 0x0160 into register r17
                          //some code to copy value r17 to char a?
 );

 if(a == 77){      
 //do something
  }
}

I'm having trouble figuring out the part where I transition from assembly back to C. How do I get the value inside register r17 and put it into a variable in the C code?

I did find this code snippet, however I don't quite understand how that works, or if that is the best way to approach this.

like image 758
user2461391 Avatar asked Jan 26 '26 19:01

user2461391


2 Answers

  __asm__ __volatile__ (
    "   ldi __tmp_reg__, 77"     "\n\t"
    "   sts 0x0160, __tmp_reg__" "\n\t"
    "   lds %0, 0x0160"          "\n\t"
    : "=r" (a)
    :
  );
like image 148
Piotr Wojtaszczyk Avatar answered Jan 28 '26 07:01

Piotr Wojtaszczyk


See here on how to inline assembly. Unless you have a very specific reason in mind, you should let the compiler take care of the variables for you. Even though you declared a in your code to be volatile, it could very well be bound to any of the 32 registers on the GP register file of the AVR core. This essentially means, the variable is never stored in RAM. If you really want to know what your compiler is doing, disassemble the final object file with avr-objdump -S and study it.

like image 36
toolazytologin Avatar answered Jan 28 '26 08:01

toolazytologin