Assistance required with inline assembler code.

I'm working through my first attempt at inline assembler. The required function is to move a value from an I/O register into a C variable.

I'm using 'LD Rd, X' and 'ST X, Rr' rather than the IN and OUT instructions, mainly because I haven't figured out what constraints should apply to values for the latter.

The address of the I/O register is in a C variable named 'regadr' and the C variable to receive its value is 'regdat'.

The Arduino IDE gives the error message:

sketch_nov28b:102: error: impossible constraint in 'asm'
** );**
** ^**

Here is the code fragment. 'i' and 'j' are defined as 'int', 'regadr' and regdat' as 'byte':

i = &regadr;
j = &regdat;

asm volatile(
  "ldi r26, 0" "\n\t"
  "ldi r27, %0" "\n\t"
  "ld __tmp_reg__, X" "\n\t"
  "ldi r27, %1" "\n\t"
  "st X, __tmp_reg__" "\n\t"
  :
  : "M" (i), "M" (j)
);

I'd be most grateful for any assistance in debugging this.

Tutorial can be found here.

OK, thanks. Looks like it might be useful, but that page at least doesn't solve the problem.

I originally inserted a clobber line to protect r26 and r27, but deleted it as part of the debugging effort to get rid of the broken constraint. I've since tried other constraints without success.

Suspecting my use of an int to pass an 8-bit value, I converted it to a byte - still no good.

I've since discovered how to code the function in C, but this uses the 64 I/O addresses rather than the 256 bottom memory addresses I was wanting, so I'm still keen to find a solution in assembler.

There's so much wrong with your code, I can't determine what you're trying to do. But I suggest looking down the page a little farther. Or start the complete tutorial series.

volatile int a;
 
asm (
  //put something inside r24/r25...
  "sts (a), r24        \n" //lsb
  "sts (a + 1), r25    \n" //msb
  : : : "r24", "r25"
);

Ah, thanks - very useful. Couldn't figure how to get a 16-bit address into an instruction. Didn't realize that it gets done by the compiler.

Got it!!!

For those interested in conundrums (conundra?) here's what works:

volatile byte regdat;
volatile int regadr,regdatp;

regdat = 0; regdatp = &regdat;
asm volatile(
 "lds r26, (regadr)" "\n\t"
 "lds r27, (regadr + 1)" "\n\t"
 "ld __tmp_reg__, X" "\n\t"
 "lds r26, (regdatp)" "\n\t"
 "lds r27, (regdatp + 1)" "\n\t"
 "st X, __tmp_reg__" "\n\t"
 : : : "r26", "r27"
);