da ich mich wunderte, warum Bascom bei den paar Codezeilen 966 Byte verbraucht, habe ich den Bascom-Code mal 1:1 in Avr-gcc umgeschrieben:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h> 	// wg. char-print

// interner RC-Oszillator 
#define F_CPU 8.0E6

//'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
#define INTERRUPT_PRELOADER 78 

#define UART_BAUD_RATE 9600    //  die gewünschte Baudrate
#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16L)-1) 

//UART -----------------------------------------------------------
char myCharBuffer[10];
char *myCharPtr;  

void UART_init(void){ 
   UBRRL |= (uint8_t) UART_BAUD_SELECT;
   UCSRB = (1<<RXEN)|(1<<TXEN); 	//Sender & Empfänger aktivieren
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); 	//Asynchron 8N1
}

void UART_transmit(uint8_t c){
   while(!(UCSRA & (1<<UDRE)));
   UDR = c;
}

void UART_transmit_string(uint8_t *string){
    while(!(UCSRA & (1<<UDRE)));
   while( *string){ UART_transmit (*string++); }
}

void UART_transmit_byte(uint8_t b){
	myCharPtr = myCharBuffer;
	myCharPtr = itoa( b,myCharPtr,10); 
	UART_transmit_string(myCharBuffer);
}

//Timing für 10 Samples Per Bit = 1,778ms
#define Samples_early 8	//Flanke Frühestens Nach 8 Samples
#define Samples_late 12	//Flanke Spätestens Nach 12 Samples
#define Samples_min 3	//Flanke Vor 3 Samples - > Paket Verwerfen

//Variablen der ISR
volatile uint8_t Sample;			//eigentlich Bit
volatile uint8_t Ir_lastsample;	//zuletzt gelesenes Sample
volatile uint8_t Ir_bittimer; 	//zählt die Aufrufe von Timer_IRQ
volatile uint16_t  Ir_data_tmp; 	//Bitstream
volatile uint8_t Ir_bitcount; 	//Anzahl gelesener Bits

//Rückgabewerte der ISR
volatile uint8_t Address_rc5; 
volatile uint8_t Command_rc5; 
volatile uint8_t Rc5_flag; //eigentlich Bit

// Initialisierung der Hardware
void ioinit()
{ 
    // Initialisiert Timer0
	TCCR0 |= (1<<CS01); 	//Prescale=8
	// TCNT0  = INTERRUPT_PRELOADER; 			//Counter
	TIMSK |= (1<<TOIE0); 	//Timer Overflow Interrupt
}

// Das Hauptprogramm 
int main()
{
    // Peripherie initialisieren
    ioinit();
	UART_init();
	
	//Pin für TSOP1736
	DDRB &= ~(1<<DDB0);	//  Eingang eh vorhanden

    // Interrupts aktivieren
    sei();

    // Eine Endlosschleife.  
    while (1)
    {
		if (Rc5_flag == 1)
		{
		Rc5_flag = 0;
		UART_transmit_string("\r\ntoggle:");
		UART_transmit_byte((Command_rc5 & (1<<7))>>7);
		
		//clear the toggle bit
        Command_rc5 &= 0b01111111;
		
		UART_transmit_string(" Adresse:");
		UART_transmit_byte(Address_rc5);
		UART_transmit_string(" Code:");
		UART_transmit_byte(Command_rc5);
		}
	}
}

// Die Interrupt Service Routine (ISR) 
SIGNAL(SIG_OVERFLOW0)
{
    TCNT0 = INTERRUPT_PRELOADER;
	Sample = !(PINB & (1<<PINB0));

    //'bittimer erhöhen (bleibt bei 255 stehen)
    if (Ir_bittimer < 255) Ir_bittimer += 1; 

    //flankenwechsel erkennen
    if (Ir_lastsample != Sample)
    {
		if (Ir_bittimer <= Samples_min) 
			{
			//flanke kommt zu früh: paket verwerfen
			Ir_bitcount = 0;
			}
		else
			{
			//nur Flankenwechsel in Bit-Mitte berücksichtigen
			if (Ir_bittimer >= Samples_early)
				{
				if (Ir_bittimer <= Samples_late) 
					{
					//Bit speichern
					Ir_data_tmp = (Ir_data_tmp << 1);
					Ir_data_tmp = Ir_data_tmp + Sample;
					Ir_bitcount +=1;
					}
					else
					{
					//Flankenwechsel zu spät: Neuanfang mit gemessener Flanke
					Ir_bitcount = 1;
					Ir_data_tmp = Sample;
					}
			   //bittimer zurücksetzen wenn Timer > Samples_early
			   Ir_bittimer = 0;
				}
			}

		//Kontrolle des Startbits auf 1
		if (Ir_bitcount == 1) Ir_bitcount = Ir_data_tmp & 1; //Bit 0

		//Alle 14 Bits gelesen?
		if (Ir_bitcount >= 14)
			{
			Command_rc5 = Ir_data_tmp & 0x3F ; //Bit 6 und 7 siehe unten
			Ir_data_tmp = (Ir_data_tmp >> 6);
			Address_rc5 = Ir_data_tmp & 0b00011111;
			//For extended RC5 code, the extended bit is bit 6 of the command.
			if ((Ir_data_tmp & (1<<6))==0) Command_rc5 |= (1<<6);
			//The toggle bit is stored in bit 7 of the command
			Command_rc5 |= ( (Ir_data_tmp & (1<<5)) <<2 );
			//Paket erfolgreich gelesen
			Rc5_flag=1;
			//paket zurücksetzen
			Ir_bitcount = 0;
			}

  }
  //sample im samplepuffer ablegen
  Ir_lastsample = Sample;
}
Trotz Compiler-Direktive "OPTIMIZE = -O2" beträgt die Codelänge in C erstaunliche 912Byte (gegenüber 966Byte in Bascom).

Fazit: Bascom macht hier keine schlechte Figur. Das Hauptproblem von Bascom ist das fehlende Registerrechnen. Ständig wird alles vom RAM hin- und hergeschaufelt. Da in GCC die Variablen für die ISR mit Volatile definiert werden müssen, kommt diese WINAVR-Optimierung nicht zum Zuge. (Volatile erfordert ca. 82 Byte zusätzlichen Code).

Markant ist in AVR-gcc die fehlende Push-Pop Orgie in der ISR:
Code:
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ ISR SIG_OVERFLOW0 in AVR-GCC ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:00BD                 push    r1
ROM:00BE                 push    r0
ROM:00BF                 in      r0, SREG
ROM:00C0                 push    r0
ROM:00C1                 clr     r1
ROM:00C2                 push    r18
ROM:00C3                 push    r24
ROM:00C4                 push    r25
...
ROM:016D                 pop     r25
ROM:016E                 pop     r24
ROM:016F                 pop     r18
ROM:0170                 pop     r0
ROM:0171                 out     SREG, r0
ROM:0172                 pop     r0
ROM:0173                 pop     r1
ROM:0174                 reti
bekanntlich langt hier Bascom ordentlich zu
Code:
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ ISR Timer0 in Bascom ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ROM:008F                 push    r0
ROM:0090                 push    r1
ROM:0091                 push    r2
ROM:0092                 push    r3
ROM:0093                 push    r4
ROM:0094                 push    r5
ROM:0095                 push    r7
ROM:0096                 push    r10
ROM:0097                 push    r11
ROM:0098                 push    r16
ROM:0099                 push    r17
ROM:009A                 push    r18
ROM:009B                 push    r19
ROM:009C                 push    r20
ROM:009D                 push    r21
ROM:009E                 push    r22
ROM:009F                 push    r23
ROM:00A0                 push    r24
ROM:00A1                 push    r25
ROM:00A2                 push    r26
ROM:00A3                 push    r27
ROM:00A4                 push    r28
ROM:00A5                 push    r29
ROM:00A6                 push    r30
ROM:00A7                 push    r31
ROM:00A8                 in      r24, SREG
ROM:00A9                 push    r24
...
ROM:0154                 pop     r24
ROM:0155                 out     SREG, r24
ROM:0156                 pop     r31
ROM:0157                 pop     r30
ROM:0158                 pop     r29
ROM:0159                 pop     r28
ROM:015A                 pop     r27
ROM:015B                 pop     r26
ROM:015C                 pop     r25
ROM:015D                 pop     r24
ROM:015E                 pop     r23
ROM:015F                 pop     r22
ROM:0160                 pop     r21
ROM:0161                 pop     r20
ROM:0162                 pop     r19
ROM:0163                 pop     r18
ROM:0164                 pop     r17
ROM:0165                 pop     r16
ROM:0166                 pop     r11
ROM:0167                 pop     r10
ROM:0168                 pop     r7
ROM:0169                 pop     r5
ROM:016A                 pop     r4
ROM:016B                 pop     r3
ROM:016C                 pop     r2
ROM:016D                 pop     r1
ROM:016E                 pop     r0
ROM:016F                 reti