|
Может ли меняться адрес переменной в стеке? |
|
|
|
Oct 5 2010, 06:39
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Допустим есть такой код: Код bool ModulesInit(uint8_t mn) { uint8_t cmd[3] = { 8, mn, 0 };
pTWI = cmd; // ... Массив cmd[] компилятор размещает в стеке. Затем его адрес присваивается другой переменной и она с ним как-то работает, причем эта переменная используется в прерывании. В связи с этим возникает вопрос: можно ли быть уверенным, что положение этого массива в ОЗУ (его абсолютный адрес) не изменится? Разумеется, при условии что из функции мы еще не вышли. Не может ли в процессе выполнения функции он как-то двигаться? Дело в том, что в таком виде наблюдались необъяснимые глюки, которые исчезли как только я объявил этот массив static. Но они и раньше иногда исчезали, поэтому нет уверенности, что их вылечил именно static.
|
|
|
|
|
Oct 5 2010, 07:32
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(777777 @ Oct 5 2010, 10:39)  ...можно ли быть уверенным, что положение этого массива в ОЗУ (его абсолютный адрес) не изменится? Разумеется, при условии что из функции мы еще не вышли. Не может ли в процессе выполнения функции он как-то двигаться?... не должен. но! 1) надо убедиться, что Вы адресуетесь _именно_к_нему_ а не по указателю на деревню бабушке. 2) (маловероятно)соглашение об очистке стэка в вызываемых подпрограммах соблюдено. 3) не происходит выхода за его размерность, при работе с ним. 4) само значение указателя ссылающегося на него не меняется все эти случаи отсекаются под низкоуровневым дебагом. либо мало инфы привели. (круглый)
|
|
|
|
|
Oct 5 2010, 08:24
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(GDI @ Oct 5 2010, 10:55)  ...Гораздо более вероятна ошибка программиста, т.е. все 4 выше приведенных пункта. Или стек переполнился, что тоже ошибка программиста. Или прерывание сработало после того, как программа покинула функцию. Цитата(777777 @ Oct 5 2010, 09:39)  Массив cmd[] компилятор размещает в стеке. Затем его адрес присваивается другой переменной и она с ним как-то работает, причем эта переменная используется в прерывании. Оооо! Какой моветон.
|
|
|
|
|
Oct 5 2010, 10:19
|

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

|
Цитата(777777 @ Oct 5 2010, 11:54)  Этот буфер находится в функции, поэтому создается на стеке. Ну а передаваться они, естественно, будут по прерываниям. Какие проблемы? Надо оставаться в функции до завершения работы прерываний. Зачем тогда прерывания? Есть еще один тонкий момент - вы объявили буфер без volatile, поэтому если во время, пока прерывание работает с буфером функция занимается чем-то еще кроме ожидания, компилятор вполне может расположить на месте этого буфера какие-то использующиеся дальше локальные переменные, ведь с его точки зрения функция уже закончила работу с буфером и он ей больше не нужен. Более того, компилятор вправе выкинуть этот буфер и его заполнение вообще, ведь занесенные в не-volatile буфер данные дальше не используются.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 5 2010, 10:44
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(MrYuran @ Oct 5 2010, 13:01)  А не проще заполнить статический буфер, дать обработчику ссылку на начало и длину и спокойно заниматься своими делами? А "свои дела" как раз и заключаются в том, чтобы опросить несколько модулей по I2C и передать с них информацию дальше. Поэтому пока она передается, делать все равно нечего, нужно стоять и ждать. Цитата(Сергей Борщ @ Oct 5 2010, 14:19)  Есть еще один тонкий момент - вы объявили буфер без volatile, поэтому если во время, пока прерывание работает с буфером функция занимается чем-то еще кроме ожидания, компилятор вполне может расположить на месте этого буфера какие-то использующиеся дальше локальные переменные, ведь с его точки зрения функция уже закончила работу с буфером и он ей больше не нужен. Более того, компилятор вправе выкинуть этот буфер и его заполнение вообще, ведь занесенные в не-volatile буфер данные дальше не используются. Обработчик прерываний ничего не знает о буферах, он работает с переменной pTWI, а она volatile. И вообще, я уже сделал буфер static, но это не помогло, глюки продолжаются, так что вопрос снимается.
|
|
|
|
|
Oct 5 2010, 16:50
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(777777 @ Oct 5 2010, 18:33)  Спасибо, кэп! если под дебагом не охота возится - есть другой ломовой способ. выключаете кусок кода. помогло? да-нет. если да - подключаете кусок кода, делите его лапополам. одну половину выключаете. операцию повторяете. если не помогло - следующий кусок кода откусываете. если после всех манипуляций у вас получилось строчек 10 кода, а всё остальное коменты - вот их (все 10) и выкладывайте сюда для помощи. а то как то гадания от телепатии уже пошли. (круглый)
Сообщение отредактировал kolobok0 - Oct 5 2010, 16:50
|
|
|
|
|
Oct 5 2010, 17:14
|

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

|
Цитата(777777 @ Oct 5 2010, 13:44)  Обработчик прерываний ничего не знает о буферах, он работает с переменной pTWI, а она volatile. Да при чем тут обработчик? Функция не знает, что этот буфер еще кому-то нужен, пусть на него хоть 10 volatile-указателей указывают.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|