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?
Lesezeichen