There isn't much point in going below 512 bytes. On the ATmega328, the smallest boot block you can have is 512 bytes, so if you go smaller you don't gain any extra program flash space. The next useful size on the 168 is 256 bytes - and I really don't think it would be possible to squeeze things that tight.
/* C zero initialises all global variables. However, that requires *//* These definitions are NOT zero initialised, but that doesn't matter *//* This allows us to drop the zero init code, saving us memory */
#if 0 // The compiler normally generates sts instructions for setting // up I/O space registers. But that takes 6 bytes per register. // This code can do it in 2, with an overhead of 20 bytes. // This starts to pay off when initialising 6 or more registers __asm__ volatile ( "ldi r30,lo8(init_table)\n" "ldi r31,hi8(init_table)\n" ............. [addr5]"i"(_SFR_MEM_ADDR(UBRR0L)), [val5]"i"((F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1) );#else // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 UCSR0A = _BV(U2X0); //Double speed mode USART0
mowcius: You can use a second Arduino as a programmer: http://arduino.cc/en/Tutorial/ArduinoISP