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

 
 
> Может ли меняться адрес переменной в стеке?
777777
сообщение Oct 5 2010, 06:39
Сообщение #1


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

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



Допустим есть такой код:
Код
bool ModulesInit(uint8_t mn)
    {
    uint8_t cmd[3] = { 8, mn, 0 };

    pTWI = cmd;
    // ...

Массив cmd[] компилятор размещает в стеке. Затем его адрес присваивается другой переменной и она с ним как-то работает, причем эта переменная используется в прерывании. В связи с этим возникает вопрос: можно ли быть уверенным, что положение этого массива в ОЗУ (его абсолютный адрес) не изменится? Разумеется, при условии что из функции мы еще не вышли. Не может ли в процессе выполнения функции он как-то двигаться? Дело в том, что в таком виде наблюдались необъяснимые глюки, которые исчезли как только я объявил этот массив static. Но они и раньше иногда исчезали, поэтому нет уверенности, что их вылечил именно static.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
GDI
сообщение Oct 5 2010, 07:55
Сообщение #2


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Как вы себе представляете "движения" стека? Это вообще-то довольно нетривиальная задача сдвинуть в памяти десяток переменных разного типа, и уж тем более это задача не для АВР, и конечно-же такого ни один компилятор не делает сам. Гораздо более вероятна ошибка программиста, т.е. все 4 выше приведенных пункта.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 5 2010, 08:24
Сообщение #3


Шаман
******

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



Цитата(GDI @ Oct 5 2010, 10:55) *
...Гораздо более вероятна ошибка программиста, т.е. все 4 выше приведенных пункта.

Или стек переполнился, что тоже ошибка программиста.
Или прерывание сработало после того, как программа покинула функцию.

Цитата(777777 @ Oct 5 2010, 09:39) *
Массив cmd[] компилятор размещает в стеке. Затем его адрес присваивается другой переменной и она с ним как-то работает, причем эта переменная используется в прерывании.

Оооо! Какой моветон.
Go to the top of the page
 
+Quote Post
777777
сообщение Oct 5 2010, 08:54
Сообщение #4


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

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



Цитата(IgorKossak @ Oct 5 2010, 12:24) *
Оооо! Какой моветон.

Это еще почему? Некая функция хочет послать данные по I2C. Для этого нужно указатель I2C установить на буфер из которого будут передаваться данные. Этот буфер находится в функции, поэтому создается на стеке. Ну а передаваться они, естественно, будут по прерываниям. Какие проблемы?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 5 2010, 09:01
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(777777 @ Oct 5 2010, 12:54) *
Это еще почему? Некая функция хочет послать данные по I2C. Для этого нужно указатель I2C установить на буфер из которого будут передаваться данные. Этот буфер находится в функции, поэтому создается на стеке. Ну а передаваться они, естественно, будут по прерываниям. Какие проблемы?

А не проще заполнить статический буфер, дать обработчику ссылку на начало и длину и спокойно заниматься своими делами?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
777777
сообщение Oct 5 2010, 10:44
Сообщение #6


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

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



Цитата(MrYuran @ Oct 5 2010, 13:01) *
А не проще заполнить статический буфер, дать обработчику ссылку на начало и длину и спокойно заниматься своими делами?

А "свои дела" как раз и заключаются в том, чтобы опросить несколько модулей по I2C и передать с них информацию дальше. Поэтому пока она передается, делать все равно нечего, нужно стоять и ждать.

Цитата(Сергей Борщ @ Oct 5 2010, 14:19) *
Есть еще один тонкий момент - вы объявили буфер без volatile, поэтому если во время, пока прерывание работает с буфером функция занимается чем-то еще кроме ожидания, компилятор вполне может расположить на месте этого буфера какие-то использующиеся дальше локальные переменные, ведь с его точки зрения функция уже закончила работу с буфером и он ей больше не нужен. Более того, компилятор вправе выкинуть этот буфер и его заполнение вообще, ведь занесенные в не-volatile буфер данные дальше не используются.

Обработчик прерываний ничего не знает о буферах, он работает с переменной pTWI, а она volatile. И вообще, я уже сделал буфер static, но это не помогло, глюки продолжаются, так что вопрос снимается.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 5 2010, 17:14
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
halfdoom
сообщение Oct 6 2010, 04:59
Сообщение #8


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

Группа: Свой
Сообщений: 1 003
Регистрация: 20-01-05
Пользователь №: 2 072



Цитата(Сергей Борщ @ Oct 5 2010, 20:14) *
Функция не знает, что этот буфер еще кому-то нужен, пусть на него хоть 10 volatile-указателей указывают.

Точнее, _компилятор_ не знает, что этот буфер еще нужен, и имеет полное право использовать под другие переменные в данной функции.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 6 2010, 08:56
Сообщение #9


Гуру
******

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



Цитата(halfdoom @ Oct 6 2010, 07:59) *
Точнее, _компилятор_ не знает,
Это я писал в сообщении №7. Тут попытался упростить.


--------------------
На любой вопрос даю любой ответ
"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

Сообщений в этой теме
- 777777   Может ли меняться адрес переменной в стеке?   Oct 5 2010, 06:39
- - kolobok0   Цитата(777777 @ Oct 5 2010, 10:39) ...мож...   Oct 5 2010, 07:32
||- - 777777   Цитата(Сергей Борщ @ Oct 6 2010, 12:56) Э...   Oct 6 2010, 09:19
||- - Сергей Борщ   Цитата(777777 @ Oct 6 2010, 12:19) Господ...   Oct 6 2010, 13:13
||- - 777777   Цитата(Сергей Борщ @ Oct 6 2010, 17:13) Т...   Oct 6 2010, 14:47
||- - Сергей Борщ   Цитата(777777 @ Oct 6 2010, 17:47) Я же н...   Oct 6 2010, 20:20
||- - kolobok0   (бормоча се под нос на ночь глядя) от посему обожа...   Oct 6 2010, 20:54
||- - Ink   Цитата(kolobok0 @ Oct 7 2010, 00:54) от п...   Oct 7 2010, 06:31
|- - Сергей Борщ   Цитата(777777 @ Oct 5 2010, 11:54) Этот б...   Oct 5 2010, 10:19
- - prottoss   Цитата(777777 @ Oct 5 2010, 13:39) Но они...   Oct 5 2010, 11:10
|- - 777777   Цитата(prottoss @ Oct 5 2010, 15:10) Как ...   Oct 5 2010, 14:33
|- - kolobok0   Цитата(777777 @ Oct 5 2010, 18:33) Спасиб...   Oct 5 2010, 16:50
- - Itch   все дело в волшебном словечке volatile Программис...   Oct 6 2010, 03:41
- - IgorKossak   Поскольку вопрос снят и так прекрасно всё закончил...   Oct 7 2010, 06:39


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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 08:59
Рейтинг@Mail.ru


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