Go Down

Topic: Inline Assembler; "Impossible constraint" for byte value > 127 (Read 1 time) previous topic - next topic


I'm trying to pass a byte to some inline assembly code.

0-127 works fine
>127 throws an 'impossible constraint' error.

I've read some gcc-avr documentation but am still stuck. Any help welcome!

Here's a sketch demonstrating my problem...

Code: [Select]

void setup() {}

void loop() {

  byte thebyte = 128;  //0-127 works, >127 causes "impossible constraint"
  asm volatile (
  "ldi r16,%[thebyte]"    "\n\t"

  [thebyte] "M" (thebyte)



Looking at the avg-gcc source, the "M" constraint that you are using only allows unsigned values (0..255).  There does not appear to be a constraint that would allow values in the signed range (-128..127).


That suggests that instruction takes a _signed_ byte offset, so the value cannot be more than 127.  Replace "byte" by "char" and 128 by -128 (unless you want +128 in which case perhaps a different instruction sequence is needed?)
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]


Oct 13, 2012, 12:20 am Last Edit: Oct 13, 2012, 12:21 am by paulo999 Reason: 1
Ok, I've sorted it.

Mistake number 1:

ldi loads an immediate value, e.g. a constant. No good for passing in values which change.

Mistake number 2:

Specifying "M" in the input parameter binding, again, it's for use with constants.

What I should have been doing is using the mov instruction, and passing in using the "r" option, so that the value goes into a register.

So, the fixed code:

Code: [Select]

void setup() {}

void loop() {

 byte thebyte = 128;  //This works as intended, right up to 255
 asm volatile (
 "mov r16,%0"    "\n\t"

   ::"r" (thebyte)


Oh and thanks Mark for having a go, and not saying "you shouldn't be using assembler" ;)

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131