I carefully followed the instructions how to write proper inline assembly for avr-gcc, however, the resulting code didn't work. I tracked down the problem and came to the conclusion that gcc assigned wrong registers to the output variable and therefore corrupted my input data.
Here's sample code, I tried to write a fast routine for multiplying a 16-bit number with an 8 bit number, the result would be written to a 32 bit number: static inline int32_t mul_16_8(uint16_t left, uint8_t right) { int32_t result; asm volatile( "clr %C0;" "\n\t" "clr %D0;" "\n\t" "mul %A1, %2;" "\n\t" "movw %A0, r0;" "\n\t" "mul %B1, %2;" "\n\t" "add %B0, r0;" "\n\t" "adc %C0, r1;" "\n\t" "clr __zero_reg__" "\n\t" :"=&r" (result) :"r" (left),"r" (right) :"r0", "r1" ); return result; } If I invoke this function from regular C code, such as int32_t res = mul_16_8(0x1234, 0x56); I get incorrect results. I believe this is the case because the "left" variable is assigned to the same registers as "result", and "left" is overwritten during the multiplication. According to several web pages the "=&r" (result) directive should prevent exactly this .... Since the bug reporting guide explicitly discourages from posting assembly code generated by the compiler, I refrain from posting it here, although it might help clarify this issue. I will post it upon request, though :) Some extra information: I don't use plain vanilla avr gcc, but the win avr version: WinAVR 20071221, which is 4.2.2 plus some AVR specific patches (some bug fixes, extra device support). Please let me know, if gcc-bugzilla is the wrong address for these bugs! -- Summary: AVR inline assembly clobbers input value Product: gcc Version: 4.2.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: inline-asm AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: Rudolf dot Leitgeb at gmx dot at GCC build triplet: i686-unknown-linux GCC host triplet: i686-unknown-linux GCC target triplet: avr http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37895