Цитата(__nik__ @ Dec 30 2007, 01:43)

еще раз хочу обратить внимание что таже программа работает в тани26....
Вы сами себе противоречите, уважаемый. Значит не та же программа. Если бы ошибка, которая у вас явно присутствует и которую вы вначале списали на камень, а потом на IAR, происходила при обращении к оборудованию, то я бы поверил. Возможно файл объявлений ошибочный или даже проблемы с оборудованием каким то. Но ошибка, возникающая при умножении с использованием плавающей запятой (то есть данный кусок раскладывается в 2 десятка простых комманд) - не поверю.
Настораживает также упоминание вами прерывания и "случайности" ошибки.
Всё это наводит на мысль, что вы столкнулись с достаточно сложной, но весьма распространенной ошибкой при написании прерывания.
Для ясности приведу два примера.
1) Пример с регистрами I/O
В голове находится следующая строчка
PORTL |= 1;
Компильнётся примерно в следующее
lds r16,portl
ori r16,1
sts portl,r16
В прерывании следующая строчка
PORTL |= 2;
А теперь посмотрите внимательно. Если прерывание придёт во время исполнения команды ori при этом бит D1 порта L в это время будет равен 0, то произойдёт следующее. В прерывании бит 1 будет установлен в 1, но сразу по выходу из прерывания он опять сбросится в 0. И вы будете в непонятках так как в голове вы с этим битом не работаете.
2) Пример с переменными
В голове находится следующие строчки
volatile uint16_t i,j;
if(i<j)...
Представим себе что i=0x1f, а j=0x23. Очевидно, что условие должно выполниться. Учитывая что переменные 16 бит, то сама операция пройдёт в 2 этапа
В прерывании следующая строчка
i++;
Представим, что прерывание произойдёт м/у сравнениями младших и старших байтов. Тогда первое сравнение будет F c 3. Потом идёт прерывание где i становится 0x20 и идёт сравнение 2 с 1. Результат - условие выполняться не будет. У вас возникнет ошибка.
Примечание: IAR пытается бороться с такими ситуациями путём предварительной пересылки регистровой пары, а потом уж самой операции. Но это я так для примера привёл. Так как если операнд 4 байта, то и это уже не спасает от потенциальной ошибки.
Проявляться такая ошибка будет крайне нерегулярно, так как необходимо:
a) прерывание в "нужном" месте
б) модификация "нужной переменной" или появление "нужного значения" переменной.
Всё это я к тому, что сама ошибка может находится совершенно не в том месте где вы её ищете, а проявляться в "давно вылизанной" части программы. И даже при внесении изменений в произвольное место менять своё поведение.