реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> WinAVR 2006, Компилятор полностью игнорирует циклы
Freeze Anti
сообщение Jan 10 2008, 09:02
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 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 !!!
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 10 2008, 09:09
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Freeze Anti @ Jan 10 2008, 12:02) *
У меня появилась такая проблема... компилятор полностью пропускает циклы... то есть вот пример...
for(short i = 0; i == 23; i++)
Такой цикл не будет выполнен ни один раз и, поэтому, транслятор код оптимизирует

Правильнее будет записать, например, так
for(short i = 0; i < 24; i++)
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 10 2008, 09:15
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 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: А про неправильный цикл я не заментил. 05.gif

Сообщение отредактировал aesok - Jan 10 2008, 09:17
Go to the top of the page
 
+Quote Post
Daskar
сообщение Jan 10 2008, 15:17
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 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 условие продолжения цикла станет ложным и цикл прекратится.
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Jan 10 2008, 16:00
Сообщение #5


Частый гость
**

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



Да, спасибо... я заметил обе ошибки... но именно объявление цикла и оператор for были ни при чем... я создал новую функцию и объявил ее volatile и вынес цикл туда... после этого он у меня исполнился...

Ошибка в операторе for была уже из-за спешки... сначала я написал его правильно smile.gif ... потом заменил цикл на while... когда это не помогло, переписал опять в виде for... уже с ошибкой...


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 10 2008, 17:21
Сообщение #6


Гуру
******

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



И еще "short i" - ни к селу ни к городу - для 8bit это работа с чрезмерно большим 16bit значением, а для
32 ARM - с исскуственно ограниченным.
Если пользоватся минимальным набором типов, то для 8bit "unsigned char" , а для 16/32 соответствено "int".
Поскольку на 8bit int обычно "традиционно" sad.gif 16bit, на 16bit - уже обычно логичный соразмерный, ну и на 32bit-овиках вообще все правильно.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 10 2008, 18:08
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Jan 10 2008, 19:21) *
Если пользоватся минимальным набором типов, то для 8bit "unsigned char" , а для 16/32 соответствено "int".
или uint_least8_t, uint_fast8_t из stdint.h - оптимальное для архитектуры значение подставится "само".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 10 2008, 21:48
Сообщение #8


Гуру
******

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



Цитата(Сергей Борщ @ Jan 10 2008, 20:08) *
или uint_least8_t, uint_fast8_t из stdint.h - оптимальное для архитектуры значение подставится "само".

Я говорил о минимальном наборе типов. Я по простоте душевной тоже за такой подход агитировал достаточно долго, пока не наступил на непонятки в IAR ARMc int_least8_t - в сложных выражениях не int sad.gif , int_fast8_t там ведет себя похожим на int. Ну, короче я свой ручкаи завел bint (base int) для такого.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jan 11 2008, 06:03
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(zltigo @ Jan 11 2008, 00:48) *
Я говорил о минимальном наборе типов. Я по простоте душевной тоже за такой подход агитировал достаточно долго, пока не наступил на непонятки в IAR ARMc int_least8_t - в сложных выражениях не int sad.gif , 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 - ?)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 11 2008, 07:02
Сообщение #10


Гуру
******

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



Цитата(Непомнящий Евгений @ Jan 11 2008, 08:03) *
А что у вас с ними за проблемы?

Иногда int_least8_t не получается эквивалентом int на 32bit платформе sad.gif
Цитата
И еще вопросик - для чего нужны типы uint_least_X, если есть uint_fast_X?

Ну, например, для конкретной платформы fast будет тягототь к размещению в регистрах а указывая все fast получаем профанацию идеи.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jan 11 2008, 07:15
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(zltigo @ Jan 11 2008, 10:02) *
Иногда int_least8_t не получается эквивалентом int на 32bit платформе sad.gif

А ваше решение? Вы просто создали "свой" int_least8_t, назвав его bint?
Цитата
Ну, например, для конкретной платформы fast будет тягототь к размещению в регистрах а указывая все fast получаем профанацию идеи.

Не совсем понял. Почему он будет тяготеть к размещению в регистрах? Это ж обычный typedef....
Т.е. вы имеете в виду, что в "стандартных" ситуация типа счетчика цикла и т.д. следует использовать uint_least_X, а в неких исключительных - uint_fast_X?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 11 2008, 07:39
Сообщение #12


Гуру
******

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



Цитата(Непомнящий Евгений @ Jan 11 2008, 09:15) *
Это ж обычный typedef....

Обычным (в смысле на стандартный тип) typedef он быть не собязан. Вот "мой" bint это действительно тупой uint на 32bit платформе...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 11 2008, 08:17
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Jan 10 2008, 23:48) *
пока не наступил на непонятки в IAR ARMc int_least8_t - в сложных выражениях не int sad.gif
Тоже хотелось бы пример. Я быстро обжегся, что он может быть совсем не байтом, и байтовое переполнение в нем использовать нельзя. Других проблем пока не было.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 11 2008, 10:27
Сообщение #14


Нечётный пользователь.
******

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



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

Цитата(zltigo @ Jan 11 2008, 09:02) *
Ну, например, для конкретной платформы fast будет тягототь к размещению в регистрах а указывая все fast получаем профанацию идеи.
IMHO, регистры тут ни при чем. "прошу минимум 8 бит, но при этом требование - максимальная скорость работы". И тут уже в процессоре с 32-битными регистрами и без команды загрузки байта с расширением знака для int_fast8_t наиболее вероятно будет использовано 32 бита, чтобы после загрузки байта не тратить время на команды, которыми расширится знак.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 11 2008, 10:47
Сообщение #15


Гуру
******

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



Цитата(ReAl @ Jan 11 2008, 12:27) *
На каком-нибудь сигнальнике без байтовой адресации будет 16 бит, на арме с вполне приличной работой с байтами - может быть и 8 и 32 - "на усмотрение".

Проблема не в усмотрении, а в том, что это "усмотрение" не всегда нравится - на том-же ARM нет "вполне приличной работы с байтами". Нет sad.gif, посему когда вдруг он вдруг компилятор иногда начинает дополнительно извращаться с какой-нибудь 24bit маской sad.gif мне это совершенно не нравится.
Цитата
IMHO, регистры тут ни при чем.

Не могу утверждать что "ни при чем" - вполне логично предположить, что это вполне может служить и заменителем давно почти всеми похереного "register". Если вдруг есть какие-то дополнительные официальные (а не очевидные трактовки fast и least) рекомендации было-бы интересно посмотреть.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01523 секунд с 7
ELECTRONIX ©2004-2016