I think I now understand what exactly each command of the below inline assembly code does (thanks to Tauno Voipio). But again, if someone with real knowledge of Atmel AVR assembly code finds a mistake, please correct my annotations. Now I rewrote this function for the ICCAVR. But since I didn't find out if and how this compiler uses constrains, I just omitted them. The result is, that the generated assembler code uses r16 instead of r24 (upper register), which is used when compiled with gcc. And the error output is: "Register 16 is not valid". How can I force ICCAVR to use upper register (e.g. the "w" constrain used with gcc)?
Thank you!
Following code works for gcc /************************************************************************* delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
*************************************************************************/ static inline void _delayFourCycles(unsigned int __count) { if ( __count == 0 ) //delay of 2 cycles __asm__ __volatile__( "rjmp 1f\n 1:" );//relative jump to label 1 //(forward decelerated) //\n(linefeed)separates //inline assembly commands //1: is label 1,with no //following code->2cycl. else //__count is not equal 0 __asm__ __volatile__ ( //4 cycles/loop "1: sbiw %0,1" "\n\t" //label 1: sbiw (subtract //immediate 1 from count) "brne 1b" //compare the result from sbiw //with 0 and brne(branch if //not equal) to label 1 //(backward decelerated) //constrains for sbiw : "=w" (__count) //"="-enables write-permission //for this register //"w"-use upper reg. pairs //(r24, r26, r28, r30) : "0" (__count) //"0"-use the same reg. for //result as __count ); }Following code does NOT work for ImageCrafts ICCAVR compiler /************************************************************************* delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
*************************************************************************/ static inline void _delayFourCycles(unsigned int __count) { if ( %count == 0 ) //2 cycles asm( "rjmp 1" "\n" "1:"); else //4 cycles/loop asm( "1: sbiw %count,1" "\n" "brne 1"); }