The size of the hex file is misleading. It takes 43 bytes to represent 16, so your executable is actually only 4 K.
That said, passing the parameter to the _delay_ms() function really blows up the code. I tried this instead, always calling the delay function with a constant, and the executable was less than 190 bytes.
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
void light_led(int longer)
{
PORTD |= (1 << 4);
if(longer) _delay_ms(1000);
else _delay_ms(500);
PORTD &= ~(1 << 4);
_delay_ms(1000);
}
void send_char(int c)
{
int i;
for(i = 1; i < 8+1; i++)
{
if(c & i) light_led(1);
else light_led(0);
}
}
int main(void)
{
DDRD |= (1 << 4);
//char text[] = {'t', 'e', 's', 't'};
int i;
for(i = 0; i < 1; i++) send_char(100);//text[i]);
return 0;
}