|
новая проблема Оптимизация компилятора IAR |
|
|
|
Mar 21 2007, 20:03
|
Частый гость
 
Группа: Новичок
Сообщений: 81
Регистрация: 9-08-06
Пользователь №: 19 445

|
Есть глобальная структура с 4 переменными которые используются во функции MiDI По адресу 01F4.
Есть функция: void MiDI(void){ while(1){ здесь код. ret //выход }; };
Данная функция вызывается из другого места по указателю на нее. Выполнив нужные действия выходим из нее, потом возвращаемся обратно, при минимальной оптимизации все нормально вот асм: 4: void MiDI (void){ +000005EF: C020 RJMP PC+0x0021 Relative jump
Но стоит повысить оптимизацию так вот получается вот что асм 4: void MiDI (void){ +00000444: 93BA ST -Y,R27 Store indirect and predecrement +00000445: 93AA ST -Y,R26 Store indirect and predecrement +00000446: EFA4 LDI R26,0xF4 Load immediate +00000447: E0B1 LDI R27,0x01 Load immediate +00000448: C020 RJMP PC+0x0021 Relative jump
СОХРАНЯЕТ В СТЕКЕ ДАННЫХ регистры R27, R26! Он думает цикл бесконечный а, я выхожу из него ! по ret (макрос), и происходит потеря данных, ведь я не восстанавливаю из стека данных. Как компилятор отучить делать вот так +00000444: 93BA ST -Y,R27 Store indirect and predecrement +00000445: 93AA ST -Y,R26 Store indirect and predecrement
|
|
|
|
|
 |
Ответов
|
Mar 22 2007, 19:04
|
Частый гость
 
Группа: Новичок
Сообщений: 81
Регистрация: 9-08-06
Пользователь №: 19 445

|
Цитата(IgorKossak @ Mar 22 2007, 14:45)  Каков смысл городить ret (макрос), если стандартного return(); вполне достаточно для корректного выхода из любого цикла, да и из функции заодно? Error[Pe118]: a void function may not return a value E:\Documens\Alex\Ìîè äîêóìåíòû\MUKS-01\MUKS01v02\task.c 10 это на return();
|
|
|
|
|
Mar 23 2007, 00:17
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Alex ma @ Mar 22 2007, 19:04)  Error[Pe118]: a void function may not return a value E:\Documens\Alex\Ìîè äîêóìåíòû\MUKS-01\MUKS01v02\task.c 10 это на return(); А что оно говорит если написать так return; // без скобочек ? Цитата(rezident @ Mar 22 2007, 19:28)  Все верно ошибку компилятор выдает. "Пустая" функция не может возвращать значение. И все же стандартизованный способ прерывания цикла это оператор break.  В крайнем случае goto на метку вне цикла. return это вполне валидный способ прекращения цикла, а вот goto - не всегда при использовании goto можно легко получать переполнение стека, если его использовать необдуманно
|
|
|
|
|
Mar 23 2007, 01:26
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Mar 23 2007, 00:50)  Легко? Cтрашилка. Никакое необдуманоое и даже преднамеренное "плохое" использование goto не должно приводить к переполнению стека или каким либо другим деструктивным последствиям при сколь-нибудь пригодном для работы компиляторе языка высокого уровня. Потеря оптимальности кода может в некоторых "необдуманных" случаях действительно заметной. goto не возвращает стек в исходное состояние, то есть если переменная была заведена на стеке то стек будет расходоваться зазря до выхода из функции ну и в принципе можно нарисовать такую ситуацию когда отведенного стека просто не хватит наверное на AVR это не очень актуальная проблемма, но например на PC легко таким образом организовать переполнение
|
|
|
|
|
Mar 23 2007, 09:07
|

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

|
Цитата(singlskv @ Mar 23 2007, 00:26)  goto не возвращает стек в исходное состояние, то есть если переменная была заведена на стеке то стек будет расходоваться зазря до выхода из функции А return, типа, возвращает, поскольку из функции выходит  . Весь обьем стека под локальные переменные выделяется сразу и соответственно освобождается сразу а не по кусочкам. Другого поведения для компиляторов с языков высокого уровня не наблюдал ни разу. В поминаемом далее PC, вообще комады enter, leave для организации единого стекового фрейма заведены.. Цитата ну и в принципе можно нарисовать такую ситуацию когда отведенного стека просто не хватит Легко, только goto к этому ни сном ни духом. Цитата наверное на AVR это не очень актуальная проблемма, Мало памяти - мало проблем  Цитата но например на PC легко таким образом организовать переполнение Каким таким "таким образом"???
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 24 2007, 01:06
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Mar 23 2007, 09:07)  А return, типа, возвращает, поскольку из функции выходит  . конечно, return; всегда востанавливает указатель стека  Цитата Весь обьем стека под локальные переменные выделяется сразу и соответственно освобождается сразу а не по кусочкам. Другого поведения для компиляторов с языков высокого уровня не наблюдал ни разу. Хорошо, сколько по вашему должен расходовать стека данных следующий код на хорошем компиляторе ? Код void func() { while(.......) { char str1[10]; ................. ................. }
while ( ........) { char str2[12]; .................. .................. } } 12 или 22 байта ? а если будут множественное goto причем как вперед так и назад ? Цитата Мало памяти - мало проблем  много регистров меньше проблем
|
|
|
|
|
Mar 24 2007, 12:32
|

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

|
Цитата(singlskv @ Mar 24 2007, 00:06)  а если будут множественное goto причем как вперед так и назад ? 1.Добавление к указанному гладкому (с точки зрения использования двух локальных массвов )алгоритму множества goto вперед/назад сдеает его просто другим и бессмысленным для сравнения с приведенным. 2.Если желаете гарантированно в любой ситуации не зависимо ни от чего иметь перекрывающиеся области памяти для массивов не используйте для них разные имена  или используйте union
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 24 2007, 12:38
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Mar 24 2007, 12:32)  1.Добавление к указанному гладкому (с точки зрения использования двух локальных массвов )алгоритму множества goto вперед/назад сдеает его просто другим и бессмысленным для сравнения с приведенным. 2.Если желаете гарантированно в любой ситуации не зависимо ни от чего иметь перекрывающиеся области памяти для массивов не используйте для них разные имена  или используйте union  1.Ну так собственно об этом и шла речь. Необдуманное goto при том же (с точки зрения результата) алгоритме может приводить к неоправданному перерасходу стека. 2. Понятно что я так вобще никогда не напишу  Это был всего лишь пример.
|
|
|
|
Сообщений в этой теме
Alex ma новая проблема Оптимизация компилятора IAR Mar 21 2007, 20:03 rezident Попробуйте выходить по break, а ret поставить посл... Mar 21 2007, 20:21 Alex ma Цитата(rezident @ Mar 21 2007, 22:21) Поп... Mar 21 2007, 21:14  rezident Цитата(Alex ma @ Mar 22 2007, 21:04) Erro... Mar 22 2007, 19:28       xemul Цитата(singlskv @ Mar 24 2007, 01:06) Хор... Mar 24 2007, 11:29         zltigo Цитата(singlskv @ Mar 24 2007, 11:38) ...... Mar 24 2007, 12:59     Rst7 Цитата(singlskv @ Mar 23 2007, 00:26) got... Mar 23 2007, 09:11 _Bill Цитата(Alex ma @ Mar 21 2007, 20:03) Есть... Mar 23 2007, 13:25 Rst7 Цитата12 или 22 байта ?а если будут множественное ... Mar 24 2007, 10:33
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|