|
WinAVR 2006, Компилятор полностью игнорирует циклы |
|
|
|
Jan 10 2008, 09:02
|

Частый гость
 
Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613

|
Здравствуйте. У меня появилась такая проблема... компилятор полностью пропускает циклы... то есть вот пример... на Си я пишу Код SetLCDPosition(2, 0); for(short i = 0; i == 23; i++) ucTemp += sCurrentTemp[i]; ucTemp /= 24; sprintf(sBuffer, "%3d", ucTemp / 2); а в ассемблере получается Код 181: SetLCDPosition(2, 0); +000002B3: 2F61 MOV R22,R17 Copy register +000002B4: E082 LDI R24,0x02 Load immediate +000002B5: 940E0113 CALL 0x00000113 Call subroutine
185: sprintf(sBuffer, "%3d", ucTemp / 2); +000002B7: 921F PUSH R1 Push register on stack +000002B8: 921F PUSH R1 Push register on stack +000002B9: E682 LDI R24,0x62 Load immediate +000002BA: E090 LDI R25,0x00 Load immediate +000002BB: 939F PUSH R25 Push register on stack +000002BC: 938F PUSH R24 Push register on stack +000002BD: 92FF PUSH R15 Push register on stack +000002BE: 92EF PUSH R14 Push register on stack +000002BF: 940E03CE CALL 0x000003CE Call subroutine моего цикла for(...) {...} нет совсем... так в нескольких местах программы (везде, где встречаются циклы) пробовал при уровнях компиляции 0, 1, 3, s. При нулевом уровне у меня программа не вылазиит из прерывания по АЦП. То есть сразу после окончания обработки прерывания сбрасывается на начало прерывания... А при остальных - проглатываются циклы... может, кто сталкивался с подобной проблемой... подскажите пожалуйста, что можно сделать... везде в программе писать такое количество операторов это уж слишком загромоздит код (циклов ожидается достаточно большое количество)...
--------------------
!!! All you need is LOVE !!!
|
|
|
|
|
Jan 10 2008, 09:15
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Freeze Anti @ Jan 10 2008, 12:02)  У меня появилась такая проблема... компилятор полностью пропускает циклы... то есть вот пример... Компилятор не пропускает циклы, он их опртимизирует. В вашем случае код Код ... for(short i = 0; i == 23; i++) ucTemp += sCurrentTemp[i]; ucTemp /= 24; sprintf(sBuffer, "%3d", ucTemp / 2); превратился в: Код ... sprintf(sBuffer, "%3d", 98); Цитата подскажите пожалуйста, что можно сделать... везде в программе писать такое количество операторов это уж слишком загромоздит код (циклов ожидается достаточно большое количество)... Прочитать про модификатор типа переменных volatile или послать ваш код сюда. Анатолий. PS: А про неправильный цикл я не заментил.
Сообщение отредактировал aesok - Jan 10 2008, 09:17
|
|
|
|
|
Jan 10 2008, 15:17
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 11-09-05
Из: Московская обл.
Пользователь №: 8 448

|
Цитата(Freeze Anti @ Jan 10 2008, 12:02)  Здравствуйте. У меня появилась такая проблема... компилятор полностью пропускает циклы... то есть вот пример... на Си я пишу Код SetLCDPosition(2, 0); for(short i = 0; i == 23; i++) ucTemp += sCurrentTemp[i]; ucTemp /= 24; sprintf(sBuffer, "%3d", ucTemp / 2); По правилам языка Си цикл выполняется в том случае когда условие цикла истинно и до тех пор пока это условие не станет ложным а переменная должна объявляется до её использования. В Вашем коде условие продолжения цикла for(short i = 0; i == 23; i++) уже ложно и цикл не будет выполнен ни разу. Переменную i надо объявить до её использования в условии цикла Код short i; for( i = 0; i < 23; i++) ... тогда при достижении переменной i значения 23 условие продолжения цикла станет ложным и цикл прекратится.
|
|
|
|
|
Jan 10 2008, 16:00
|

Частый гость
 
Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613

|
Да, спасибо... я заметил обе ошибки... но именно объявление цикла и оператор for были ни при чем... я создал новую функцию и объявил ее volatile и вынес цикл туда... после этого он у меня исполнился... Ошибка в операторе for была уже из-за спешки... сначала я написал его правильно  ... потом заменил цикл на while... когда это не помогло, переписал опять в виде for... уже с ошибкой...
--------------------
!!! All you need is LOVE !!!
|
|
|
|
|
Jan 10 2008, 17:21
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
И еще "short i" - ни к селу ни к городу - для 8bit это работа с чрезмерно большим 16bit значением, а для 32 ARM - с исскуственно ограниченным. Если пользоватся минимальным набором типов, то для 8bit "unsigned char" , а для 16/32 соответствено "int". Поскольку на 8bit int обычно "традиционно"  16bit, на 16bit - уже обычно логичный соразмерный, ну и на 32bit-овиках вообще все правильно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 11 2008, 06:03
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(zltigo @ Jan 11 2008, 00:48)  Я говорил о минимальном наборе типов. Я по простоте душевной тоже за такой подход агитировал достаточно долго, пока не наступил на непонятки в IAR ARMc int_least8_t - в сложных выражениях не int  , int_fast8_t там ведет себя похожим на int. Ну, короче я свой ручкаи завел bint (base int) для такого. А можно поподробней? У меня везде юзаются типы вроде byte (как типичная замена int), uint. ulong. Сейчас возникла необходимость один и тотже код исполнять как на компе (VC++), так и на МК. Начал переползать на uint_X, uint_fast_X. Вроде все получается неплохо. А что у вас с ними за проблемы? И еще вопросик - для чего нужны типы uint_least_X, если есть uint_fast_X? (Т.е. uint_X - фиксированный размер, uint_fast_X - самый быстрый тип размера не менее чем, а uint_least_X - ?)
|
|
|
|
|
Jan 11 2008, 07:02
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Непомнящий Евгений @ Jan 11 2008, 08:03)  А что у вас с ними за проблемы? Иногда int_least8_t не получается эквивалентом int на 32bit платформе Цитата И еще вопросик - для чего нужны типы uint_least_X, если есть uint_fast_X? Ну, например, для конкретной платформы fast будет тягототь к размещению в регистрах а указывая все fast получаем профанацию идеи.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 11 2008, 07:15
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(zltigo @ Jan 11 2008, 10:02)  Иногда int_least8_t не получается эквивалентом int на 32bit платформе  А ваше решение? Вы просто создали "свой" int_least8_t, назвав его bint? Цитата Ну, например, для конкретной платформы fast будет тягототь к размещению в регистрах а указывая все fast получаем профанацию идеи. Не совсем понял. Почему он будет тяготеть к размещению в регистрах? Это ж обычный typedef.... Т.е. вы имеете в виду, что в "стандартных" ситуация типа счетчика цикла и т.д. следует использовать uint_least_X, а в неких исключительных - uint_fast_X?
|
|
|
|
|
Jan 11 2008, 10:27
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(zltigo @ Jan 11 2008, 09:02)  Иногда int_least8_t не получается эквивалентом int на 32bit платформе  А он и не обязан. Гарантируется только то, что будет минимум 8 бит. "прошу минимум 8 бит, остальных требований не имею, на усмотрение компилятора". Сколько - как выйдет. На каком-нибудь сигнальнике без байтовой адресации будет 16 бит, на арме с вполне приличной работой с байтами - может быть и 8 и 32 - "на усмотрение". Цитата(zltigo @ Jan 11 2008, 09:02)  Ну, например, для конкретной платформы fast будет тягототь к размещению в регистрах а указывая все fast получаем профанацию идеи. IMHO, регистры тут ни при чем. "прошу минимум 8 бит, но при этом требование - максимальная скорость работы". И тут уже в процессоре с 32-битными регистрами и без команды загрузки байта с расширением знака для int_fast8_t наиболее вероятно будет использовано 32 бита, чтобы после загрузки байта не тратить время на команды, которыми расширится знак.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jan 11 2008, 10:47
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(ReAl @ Jan 11 2008, 12:27)  На каком-нибудь сигнальнике без байтовой адресации будет 16 бит, на арме с вполне приличной работой с байтами - может быть и 8 и 32 - "на усмотрение". Проблема не в усмотрении, а в том, что это "усмотрение" не всегда нравится - на том-же ARM нет "вполне приличной работы с байтами". Нет  , посему когда вдруг он вдруг компилятор иногда начинает дополнительно извращаться с какой-нибудь 24bit маской  мне это совершенно не нравится. Цитата IMHO, регистры тут ни при чем. Не могу утверждать что "ни при чем" - вполне логично предположить, что это вполне может служить и заменителем давно почти всеми похереного "register". Если вдруг есть какие-то дополнительные официальные (а не очевидные трактовки fast и least) рекомендации было-бы интересно посмотреть.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|