Accessing a C++ static variable from gcc inline asm For some reason I want to mix a bit of assembly with C++ (not C).
To allow the code to be compilable using the standard Arduino IDE, I don't want to use direct assembly source.
I don't want to use a wrapper C file either.
My problem is as follows:
I have a class with a single instance (implementing some kind of driver) that looks like this:
class cDriver {
public:
    char ISR_param;
    // ...
};

cDriver Driver;

If I want to access the ISR_param of this single instance from within an ISR, I can do something like:
ISR (TIMER2_COMPA_Vect) {
    do_something_with (Driver.ISR_param);
}

This works like a charm: the address of Driver.ISR_param beign a constant, the compiler simply generates an lds r24, &amp;Driver.ISR_param instruction to load the proper byte as a parameter for do_something_with.
Now when I try to replicate the same mechanism with inline assembler, things get a lot more complicated.
The address of Driver.ISR_param is only known to the C++ compiler as an mangled label, and I can't find a way to pass it to the inline assembler to generate the equivalent lds r24, &lt;&amp;Driver.ISR_param&gt;.
trying to remane the variable
The renaming of variables for assembly like so:
char global_var asm(&quot;my_var&quot;);

and an attempt to use it like so:
asm (&quot;lds r24, my_var\n&quot;);

will compile, but produce a linker error (my_var is undefined).
Looking at the object symbol table, the only label for global_var is a C++-like mangled name.
However hard I tried this renaming trick, I could not bring the compiler to generate a my_var label.
trying to use asm constraints
A constraint like
asm (lds r24, %0\n&quot; : : &quot;I&quot;(&amp;global_var));

will simply not compile. I scoured the possible parameter types and could not find a way to let the assembler know about this bloody address.
a terribly awkward workaround
The only way I found to make the compiler generate this dreaded lds r24,... instruction is to perform an actual function call.
So you can do something like:
__attribute__((always_inline)) give_me_my_friggin_variable(char data)
{
    asm volatile (&quot;cmp  %0,%0\n&quot;::&quot;r&quot;(data));
}   

ISR (TIMER2_COMPA_Vect, ISR_NAKED) {

    &lt;some prologue to save SREG and all needed registers&gt;

    //...

    give_me_my_friggin_variable(Driver.ISR_param);

    // continue assembly code with r24 properly initialized
}

That will generate:
    lds r24, &lt;the proper address&gt; // added by the compiler...
    cmp r24,r24                   // ...because of the register constraint here

Well, that sort of works, but at the cost of generating a totally useless instruction.
so my question is...
Is there a simpler way to let the assembler know about addresses of C++ static variables?
Try this:

asm volatile("lds r24, %0" : : "i" (&amp;Driver.ISR_param));


The "i" constraint means you provide an integer constant. It can be
any integer, unlike the uppercase "I" constraint which is limited to
6-bit positive integers.

Addendum:
The constraints supported by gcc are listed in the gcc documentation,
section Constraints for asm Operands:


The "i" constraint is listed in the subsection “Simple Constraints”
and is described as:



  An immediate integer operand (one with constant value) is allowed.
  This includes symbolic constants whose values will be known only at
  assembly time or later.



The "I" constraint is in the subsection “Machine Constraints” and,
for the AVR architecture, is defined as



  Constant greater than -1, less than 64.