Ich staune gerade, wie bescheuert der C Compiler diesen Code optimiert:
Code:
ISR(TIMER0_COMP_vect) {
    if (++ICR1L==100) {
        ICR1L=0;
        system_time++;
    }
}
Ergibt compiliert:
  • push r1
    push r0
    in r0, 0x3f
    push r0
    eor r1, r1
    push r24
    push r25
    push r26
    push r27
    in r24, 0x26
    subi r24, 0xFF
    out 0x26, r24
    in r24, 0x26
    cpi r24, 0x64
    brne .+40
    out 0x26, r1
    lds r24, 0x006A
    lds r25, 0x006B
    lds r26, 0x006C
    lds r27, 0x006D
    adiw r24, 0x01
    adc r26, r1
    adc r27, r1
    sts 0x006A, r24
    sts 0x006B, r25
    sts 0x006C, r26
    sts 0x006D, r27
    pop r2
    pop r26
    pop r25
    pop r24
    pop r0
    out 0x3f, r0
    pop r0
    pop r1
    reti


1) Mehrfache Ein/Ausgabe in das Register ICR1L (rot):
Wieso wird r24 zuerst in das I/O Register geschrieben und direkt danach wieder eingelesen? Der zweite Befehl ist doch total überflüssig, oder?

2) Schlecht platzierte Push/Pop für Register (blau):
Solange mein prescaler (also ICR1L bzw. r24) nicht 100 ist, werden die Register r25-r27 gar nicht verwendet. Dennoch werden sie schon bei Eintritt in die Funktion auf dem Stapel gesichert.

Das ganze ärgert mich deswegen, weil diese Interrupt Routine mit 100.000 mal pro Sekunde aufgerufen wird, da tut jeder unnötige Befehl richtig weh.

Hat vielleicht jemand eine Idee, wie man den Compiler zu etwas mehr Intelligenz bewegen kann?