Electronic – AVR: problem with inline assembler

avravr-gcc

WinAVR seems to produce a lot of useless code, e.g. for following C method

ISR(INT0_vect) {
    TCCR1B = 0x09;
}

it produces (-Os)

PUSH      R1             Push register on stack
PUSH      R0             Push register on stack
IN        R0,0x3F        In from I/O location
PUSH      R0             Push register on stack
CLR       R1             Clear Register
PUSH      R24            Push register on stack
LDI       R24,0x09       Load immediate
STS       0x0081,R24     Store direct to data space
POP       R24            Pop register from stack
POP       R0             Pop register from stack
OUT       0x3F,R0        Out to I/O location
POP       R0             Pop register from stack
POP       R1             Pop register from stack
RETI                     Interrupt return

although

PUSH      R0            Push register on stack
LDI       R0,0x09       Load immediate
STS       0x0081,R0     Store direct to data space
POP       R0            Pop register from stack
RETI                    Interrupt return

should be sufficient. Because these extra commands take time, my question: how to tell the compiler to produce only the required code? Or is there a tool which can optimize the byte code directly?

UPDATE:
I've tried

ISR(INT0_vect, ISR_NAKED) {
    asm volatile(
    "push r0             \n\t"
    "ldi  r0, %[value]   \n\t"
    "sts  %[ioReg], r0   \n\t"
    "pop  r0             \n\t"
    "reti                \n\t"
    : // output
    : // input
       [ioReg] "M" (_SFR_IO_ADDR(TCCR1B)),
       [value] "M" (0 << ICNC1
                  | 0 << ICES1 
                  | 0 << WGM13 
                  | 1 << WGM12
                  | 0 << CS12
                  | 0 << CS11 
                  | 1 << CS10)
    );
}

but the compiler complains:

c:\temp/ccjBxDFz.s: Assembler messages:
c:\temp/ccjBxDFz.s:30: Error: register number above 15 required

I've read a lot of AVR inline assembler documentation/tutorials, but can't get it to compile.

Best Answer

Why not use an inline assembly statement to do what you want?

See the inline assembler cookbook

A simple (readable) multiline example from there (a very short delay) which can go right into your AVR-GCC program:

asm volatile("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ::);

Since you seem to know your assembly, you should be good ready to rock with inline assembly as well.