Inline assembler giving error at assembly time

I'm experimenting with inline assembly language code on the Arduino. Here is the "loop" part of my sketch (the "setup" part just does Serial.begin()).

void loop() { unsigned int blah = 0x0407; byte output; asm volatile ("\n\t" "ld %0, %1\n\t" : "=r" (output) : "m" (blah) ); Serial.println(output); delay(20000); }

What this should do is either print 4 or 7 to the Serial console every 20 seconds (I'm not sure which; the purpose of the program is actually to find out just that: how avr-gcc handles multi-byte values). Instead, it gives me an assembler error: "Error: garbage at end of line". What's going wrong? More importantly, how can I view the assembler's output so that next time this happens I can figure it out for myself?

You need to change your "ld %0, %1" to an "ldd %0, %1"; it looks like automatic variables are handled via indirect references to the stack, which doesn't match up with "LD"

As to how to figure this out... Turn on build.verbose in your arduino preferences, and you'll see the compile command for the .cpp file go by. Something like:

/Applications/arduino/arduino-0018/Arduino-0018.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++
       -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega168 -DF_CPU=16000000L
       -DARDUINO=18 -I/Applications/arduino/arduino-0018/Arduino-0018.app/Contents/Resources/Java/hardware/arduino/cores/arduino
       /var/folders/Xw/XwjZcQ842RWmnU+8ZSLT7U+++TI/-Tmp-/build7288402800056290521.tmp/negativemodulous.cpp
       -o/var/folders/Xw/XwjZcQ842RWmnU+8ZSLT7U+++TI/-Tmp-/build7288402800056290521.tmp/negativemodulous.cpp.o

Copy and paste this into a shell window; Replace the "-c" with "-S" to save the assembler intermediate version, and replace the "-o ...sketch.cpp.o" with "-o mysketch.S" to tell it where. Then you'll be able to look at the "bad" assembler code directly, and you can run it through the compiler again to get a line number that's bad IN the assembler rather than (maybe) the original .cpp file. In this case, it was pointing to a line:

      ld r22, Y+1

(r22 is presumably "output", and "Y+1" is the pointer to blah. Except that this format isn't legal for "ld", but only "ldd."

The AVR is little-endian (low byte in low addess), as implied by the way the 16bit index registers work, and by ADIW. (though I had a pretty hard time finding a spot that said "Xlow = R26, Xhigh=R27" as opposed to just using ambiguous terms like "XLO" !) avr-gcc is also little-endian, although in principle it would be possible for it to go either way, since nearly all of the instructions work on one byte at a time.

Thank you so much. That entirely solved the problem.