Go Down

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

paulo999

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)
    );

}


MichaelMeissner

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).

MarkT

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 won't respond to messages, use the forum please ]

paulo999

#3
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!

Arduino
via Egeo 16
Torino, 10131
Italy