Цитата(SergeyBorshch @ Apr 28 2008, 22:00)

А если переменные объявлены все как extern, то может компилятор так делать?
extern или нет - не важно. Вот, смотрите простой пример:
Код
extern bool flag;
void Test()
{
flag = false;
for(;;)
if(flag == true)
{
__no_operation();
flag = false();
}
}
Здесь компилятор имеет полное право выкинуть проверку условия и все, что внутри условного оператора - ведь он видит, что переменной было присвоено false и нигде не было присвоено true. Зачем же делать бессмысленную работу? Если он будет о каждой переменной строить предположения, никакой оптимизации не получится. Компилятор может поступить и иначе - считать flag в регистр перед циклом и на каждом проходе цикла проверять содержимое регистра. Результат будет таким же плачевным - реальное изменение flag на регистре никак не отразится. А если бы он так не поступал, вы бы в другом месте сразу закричали "зачем он снова считывает переменную в регистры, он же ее вот буквально пару команд назад считывал уже". На этом и основана оптимизация - компилятор выкидывает все лишнее и только вы можете знать, в каких именно случаях оно совсем не лишнее. И вы имеете все инструменты, чтобы объяснить это компилятору. Вот если бы flag был объявлен как extern bool volatile flag; то компилятор был бы обязан при каждом обращении к flag считывать ее значение и уже не мог бы предполагать, что она останется неизменной.
Цитата(SergeyBorshch @ Apr 28 2008, 22:00)

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
Снова все правильно. У вас в одном выражении в качестве аргумента более одного раза встречается переменная с квалификатором volatile. А порядок вычисления подвыражений стандартом не определен - это решает оптимизатор, как ему покажется лучше. И он вас честно предупреждает, что сегодня он скомпилил доступ к volatile-переменным в одном порядке, а завтра может скомпилить в другом порядке. Вот пример, почему это может быть опасно:
Код
uint16_t word = ADCL | (ADCH << 8);
Каждое чтение ADCH обновляет содержимое пары ADCH:ADCL следующим результатом АЦП. И сегодня вы подав на вход половину опоры получите word = 0x0200, а после перекомпиляции вполне можете получить 0x0002, причем эти 0x00 и 0x02 будут от разных измерений. Чтобы явно указать компилятору порядок чтения volatile-переменных, надо завести временную переменную:
Код
uint16_t word;
{
uint8_t Tmp = ADCL;
word = Tmp | (ADCH << 8);
}
Посмотрите еще
вот эту ветку. Там обсасывался подобный случай.
Цитата(SergeyBorshch @ Apr 28 2008, 22:00)

И результат то же, не работает программа, т.е. не выполняет куски программы.
Очень трудно найти ошибку телепатически, не видя ни исходника ни листинга.
Цитата(SergeyBorshch @ Apr 28 2008, 22:00)

Пробывал поставить оптимизацию Medium - в этот раз выдает ошибку:
Это бага, но никак не связанная с вашими проблемами: допишите в начало scmRTOS_Target_asm.s90 перед строчкой #if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 1) строчку
Код
#define A90_PROC_OPTION ((__TID__ >> 4) & 0x0F)