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

 
 
 
Reply to this topicStart new topic
> Локальные переменные и возврат из функции, EWARM, STM32F407
drozel
сообщение Oct 22 2015, 07:36
Сообщение #1


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Наткнулся на какой-то цирк с конями: в функции используется локальный массив из 10 байт, он ложится в стек, а при возврате программа не отбрасывает эти элементы, а прямо их засовывает с R0-R2, PC, получая, естественно, hardFault.
Код
void protocolOnRxed (uint8_t *buffer, uint32_t len)
{
gLen = len;
char test[10];
gLen = sprintf(test, "Transfer: %d", len);
cdcacm_data_tx(test, gLen);
}


Я раньше не работал плотно с дизассемблером, не знаю, как там IAR должен разруливать возврат, но он явно должен знать, сколько локальных переменных выделено в стеке и выкидывать их, прежде чем считывать регистры для возврата. Так ведь?

В приложении скриншот, там видно и программу, и стек, и дизассемблер.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Obam
сообщение Oct 22 2015, 07:55
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(drozel @ Oct 22 2015, 11:36) *
Наткнулся на какой-то цирк с конями: в функции используется локальный массив из 10 байт, он ложится в стек, а при возврате программа не отбрасывает эти элементы, а прямо их засовывает с R0-R2, PC, получая, естественно, hardFault.
Код
void protocolOnRxed (uint8_t *buffer, uint32_t len)
{
gLen = len;
char test[10];
gLen = sprintf(test, "Transfer: %d", len);
cdcacm_data_tx(test, gLen);
}


Я раньше не работал плотно с дизассемблером, не знаю, как там IAR должен разруливать возврат, но он явно должен знать, сколько локальных переменных выделено в стеке и выкидывать их, прежде чем считывать регистры для возврата. Так ведь?

В приложении скриншот, там видно и программу, и стек, и дизассемблер.


А что там за Warnings на вызовы ещё двух п/п?


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 22 2015, 07:56
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Какой-то трэш и угар. Что-то я не верю, что яр может нагенерить такой код. Или я что-то не понимаю...
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 22 2015, 08:21
Сообщение #4


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(scifi @ Oct 22 2015, 13:56) *
Какой-то трэш и угар. Что-то я не верю, что яр может нагенерить такой код. Или я что-то не понимаю...

А я о чем! Но я же правильно локализовал проблему? Скрин убедителен?
Немного подробностей: портирую openlibcm3, возможны проблемы со стартапом, но вроде стек в норме.

Цитата(Obam @ Oct 22 2015, 13:55) *
А что там за Warnings на вызовы ещё двух п/п?

implicity declarations


---
UPD: Нет, похоже, дело в чем-то другом. Я попробовал создать еще одну функцию с локальным массивом, все выглядит так же, но возвращается нормально. Проблема где-то в другом месте, похоже

Сообщение отредактировал drozel - Oct 22 2015, 08:43
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 22 2015, 08:43
Сообщение #5


Гуру
******

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



Все гораздо проще. Под test автор выделяет 10 байт. После чего пишет туда строку "Transfer: ", которая уже сама занимает 11 байт. Надо ли говорить, куда будет записано текстовое представление переменной len? Так что стек как раз не в норме, он тщательно порушен.


--------------------
На любой вопрос даю любой ответ
"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
drozel
сообщение Oct 22 2015, 08:44
Сообщение #6


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(Сергей Борщ @ Oct 22 2015, 14:43) *
После чего пишет туда строку "Transfer: ", которая уже сама занимает 11 байт. Надо ли говорить, куда будет записано текстовое представление переменной len?

Черт! Напоролся, как школьник cranky.gif
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 8 2015, 08:12
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(drozel @ Oct 22 2015, 11:44) *
Черт! Напоролся, как школьник cranky.gif


пользуйте sNprintf() в котором sizeof( TargetMemArray )
Go to the top of the page
 
+Quote Post

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

 


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


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