Вобщем есть простой исходник. Код (Text): #define F_CPU 1000000UL #include <stdlib.h> #include <avr/io.h> #include <string.h> #include <stdio.h> void uart_9600(void) { #define BAUD 9600 #include <util/setbaud.h> UBRRH = UBRRH_VALUE; UBRRL = UBRRL_VALUE; #if USE_2X UCSRA |= (1 << U2X); #else UCSRA &= ~(1 << U2X); #endif UCSRB|=(1<<RXEN)|(1<<TXEN); } int uart_putchar(char c, FILE *stream); FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE); int uart_putchar(char c, FILE *stream) { if (c == '\n') uart_putchar('\r', stream); loop_until_bit_is_set(UCSRA, UDRE); UDR = c; return 0; } int main(void) { uart_9600(); stdout = &mystdout; while(1) { printf("Hello World\n"); } return 0; } Компилим его: Program: 450 bytes (2.7% Full) (.text + .data + .bootloader) Data: 32 bytes (3.1% Full) (.data + .bss + .noinit) Далее меняем строчку Код (Text): printf("Hello World\n"); на Код (Text): printf("Hello World\n "); Компилим и: Program: 1788 bytes (10.9% Full) (.text + .data + .bootloader) Data: 34 bytes (3.3% Full) (.data + .bss + .noinit) Т.е добавили один пробел и получили лишний килобайт. Хотя при отладке этот килобай не наблюдаю. Такое ощущение, что у компилятора от пробела сносит башню. Это глюк? ЗЫ: Eclipse+WinAVR-20100110
Мдя printf реализован весьма убого. При попытке вывести данных типа float к прошивке накидывается еще пару Кб.
2Black_mirror: Во ремя отладки я смотрел листинг на асме. Он увеличелся незначительно. Просто какого черта winavr добавляет к прошивке какой то мусор.
2KeSqueer: Что то я глубоко сомниваюсь, что функция вывода константы типа float занимает пару Кб. Темболее я наблюдал, пошагово в отладчике за дизассеблированым кодом. Длинных функций нет. Весь код который выполняется занимает отсилы байт 500-600. Спрашивается зачем тогда компилятор добавляет ненужный код который даже не выполняется?
a9d А сколько по вашему мнению должна занимать функция для вывода float? Чтобы она ей можно было указать сколько символов выводить до точки, сколько после, выводить ли порядок, дополнять ли число нулями, выводить ли всегда знак, чтобы правильно выводила всякие плюс/минус бесконечности и "не числа", и еще чтобы все вычисления делала на 8 разрядных регистрах, причём из операций, одним из операндов которых является память, можно использовать только загрузку и сохранение, все остальные операции выполнять только с регистрами. После того как ответите на первый вопрос, сможете предъявить ваш ответ, код то есть?
Полазил в сети и кое что нарыл. 1) Функцией printf почти никто не пользуется. Т.к если ей не указывать на конец строки "\n", то компилятор к прошивке прицепит комплект функций по работе со строками. Поэтому используют функцию fprintf(&mystdout," Hello "); . 2) Работу с дробными числами WinAVR оптимизирует хорошо. Но вывод через функцию print(и ее аналогии) происходит через заднее место. Т.к. компилятор к прошивке прицепит комплект функций по работе со строками + функции преобразования. Поэтому используют: Код (Text): char mystr[16]; char mystr1[16]; double d=3.14433; int j=0; itoa((int)d,mystr,10); j=(d-(int)d)*100; itoa(j,mystr1,10); fprintf(&mystdout,"%s",mystr); fprintf(&mystdout,"."); fprintf(&mystdout,"%s",mystr1); fprintf(&mystdout,"\n"); В этом случае лишнего багажа не будет.
Забыл написать. В этом случае размер прошивки(в прошивку добавлены строки из второго пункта) уменьшается до 628 байт(код прошивки приведен выше). Если же использовать printf (&mystdout,"%.5f",MyDouble) для вывода переменной типа float, то размер прошивки будет составлять 1938 байт. Разница очевидна.
На самом деле немного. Но обычно компилятор с линкером подгружают сразу пачку подпрограмм или подпрограмма пишется универсально - вот вам и кило.