QUOTE (alexxack @ Jul 1 2013, 09:01)

возможно я попутал проект щас выложу исправленный еще раз который у меня компилится без проблем.
Похоже. Этот собирается.
QUOTE (alexxack @ Jul 1 2013, 09:01)

Честно говоря проект для меня довольно большой в силу того что занимаюсь ассемблером всего месяц и пока что не нашел мест где вектора объявляются.
В вашем случае (смешанный C/Asm проект) вектора объявляются в библиотечном модуле crt (старатп-код). Компилятор подставляет подходящий для вашего процессора стартап, так что с размером векторов все в порядке.
Первое, что бросилось в глаза - судя по содержимому области векторов в листинге - прерывания вы не используете (во всяком случае в вектора не попал ни один обработчик прерывания), но при этом вы их разрешаете в main(). Одно из двух - либо "неаккуратненько", либо вы все же используете прерывания, но назвали обработчики векторов неправильно, поэтому стартап-код их не нашел и не подсоединил к проекту.
Второе - вы почему-то размещаете переменные в секции .noinit. Однако само название этой секции говорит о том, что переменные вам придется инициализировать самому, врукопашную. Гораздо проще поместить переменные в секцию .bss (те, что должны быть обнулены перед запуском) и .data (которым должно быть присвоено отличное от нуля значение) и стартап-код проинициализирует переменные двумя короткими циклами. Это займет гораздо меньше места и выполнится быстрее, чем ваша инициализация каждой переменной в каждом модуле.
Третье - за "магические числа", подобные этим:
CODE
ldi r16, 0x85
sts _SFR_IO_ADDR( ADCSRA ), r16 //168
надо бить линейкой по рукам. Пришлось лезть в даташит и тратить время чтобы перевести это число в осмысленный вид:
CODE
ldi r16, (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0)
Тут сразу видно, какие биты выставлены. А вы будете тратить это время каждый раз, пытаясь что-то изменить или исправить в своем коде с "магическими числами". Доверьте перевод битов в байты машине. Она железная, она не ошибается. "Машина должна работать, а человек - думать" (принцип IBM).
Ну и в файле ModBus.s находим первые ошибки:
1)
CODE
USART_RXC_vect: // ----------------------- прерывание по поступлению символа -------------------------------------------------
А если посмотреть в файл io.h, включаемый в него iom168.h и включаемый в последний iomx8.h (они находятся в папках компилятора), то можно найти несколько другое имя этого обработчика для atmega168:
CODE
/* USART Rx Complete */
#define USART_RX_vect_num 18
#define USART_RX_vect _VECTOR(18)
#define SIG_USART_RECV _VECTOR(18)
/* USART, Data Register Empty */
#define USART_UDRE_vect_num 19
#define USART_UDRE_vect _VECTOR(19)
#define SIG_USART_DATA _VECTOR(19)
/* USART Tx Complete */
#define USART_TX_vect_num 20
#define USART_TX_vect _VECTOR(20)
#define SIG_USART_TRANS _VECTOR(20)
Лучи поноса за это многообразие названий одних и тех же векторов в разных кристаллах можно посылать в сторону нашего друга Атмела.
2)
CODE
ldi r22, 0xC0
// out _SFR_IO_ADDR( UCSRB ), r22
// out _SFR_IO_ADDR( UCSRC ), r23
sts _SFR_IO_ADDR( UCSR0B ), r22 //168
sts _SFR_IO_ADDR( UCSR0C ), r23 //168
Вот вам и первая злая шутка с "магическими числами": если проследить выше по тексту содержимое регистра R23, вы переводите USART в недокументриованный (зарезервированный) режим. А если бы вы использовали символические имена битов - компилятор бы выругался, ибо по сравнению с мегой8 изменилось назначение и название некоторых битов в в этом регистре.
3) Далее меня заинтересовало, почему не подсоединился вектор с, казалось бы, правильно написанным именем "TIMER0_OVF_vect". А ответ прост - вы не указали, что эта метка глобальная. Вот так вектор попадает в таблицу:
CODE
.global TIMER0_OVF_vect
TIMER0_OVF_vect: // ----------------------- прерывание по переполнению TIMER0 -------------------------------------------------
Понятное дело, метки входа в остальные обработчики также должны быть глобальными.
Надеюсь, остальные подобные ошибки вы найдете самостоятельно.