Перейти к содержанию
    

Stack, 8-byte alligment, откуда ноги?

Вчера ловил интересный глюк, с UcOS, достаточно добавить переменную любую почти в любом месте кода и все рушилось. Но если добавить ещё одну - снова работало. Оказалось в итоге что это меняет положение стека задач в оське, и если он не 8allign то рушится. В доках Арм что то о требовании такого выравнивания для внешней памяти. Но тут то внутренняя. Откуда ноги, ткните плз. Просто ради интереса

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Откуда ноги, ткните плз. Просто ради интереса

LDRD/STRD, работа с 64-битными данными.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

LDRD/STRD, работа с 64-битными данными.

Ну хорошо, я решил свою проблему, создав сегмент с аллигн 8 и поместив в него стеки задач ос. Но до того, обычный проект совершенно, у него стек просто на конец озу чипа, в сегменте с алигн4. Почему работает? Да и все равно не совсем ясно, если в стек пушить 4байтные данные, то ведь станет криво. Чего то не понимаю я. Или арм при заталкивании в стек, допустим одного байта, на самом деле меняет указатель стека на 8? Компа нет под рукой, но стало интересно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да и все равно не совсем ясно, если в стек пушить 4байтные данные, то ведь станет криво.

При вызове функции должно быть ровно, в остальное время все равно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть компилер при вызове примет меры для выравнивания, зная что стек в 8байтном сегменте? А во всех этих хелло ворд как такое соблюдается? Просто потому что конец озу и так кратен 8 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть компилер при вызове примет меры для выравнивания, зная что стек в 8байтном сегменте?

Да, примет.

 

А во всех этих хелло ворд как такое соблюдается? Просто потому что конец озу и так кратен 8 ?

Про всякие хелло ворды ничего не скажу, но требованию уже много лет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это связано с выравниванием стекового фрейма к двойному слову. Это можно отключить в NVIC регистр CCR бит STKALIGN, после чего выравнивание будет к слову. Но отключать можно не во всех МК, m7 нельзя точно. По идее падало во время переключения задач, т.е. при вызове прерывания.

Изменено пользователем MasterElectric

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

LDRD/STRD, работа с 64-битными данными.

Это не так. LDRD/STRD требуют выравнивания только на 4.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не так. LDRD/STRD требуют выравнивания только на 4.

- Не на всех архитектурах это разрешено по умолчанию (ARMv5TE, ARMv6)

- Эффективнее работать с выравниванием (ARMv7-M)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В доках Арм что то о требовании такого выравнивания для внешней памяти. Но тут то внутренняя. Откуда ноги, ткните плз.

Они ссылаются на LDRD, STRD, причём в разных вариантах архитектуры ARM эффект может быть или не быть, но сделали стандартом, чтобы не путаться. Тут.

 

Оказалось в итоге что это меняет положение стека задач в оське, и если он не 8allign то рушится.

Компилятор, зная, что стек выравнен на 8 байт, может использовать такую арифметику с адресами, которая ломается при отсутствии выравнивания. Вот пример.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Итого в линкер файлах того же gcc мина лежит? Там везде стек а аллигн4 сегментах. Либо его библиотеки и соглашения о вызовах нечуствительны к этому, а fault я получаю потому что ucOS что то там упускает? Она явно написана с требованием аллигн8, в вариантах под IAR везде pragma locaton stacks, и он в icf отдельно обьявлен с аллигн8. Хотелось бы понять, причина в ОСи такой, или все же аллигн8 необязателен без нее?

 

И еще тупой вопрос. Сегменты с аллигнами это ведь для линкера. Компилятор вообще в курсе?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотелось бы понять, причина в ОСи такой, или все же аллигн8 необязателен без нее?

Обязателен, т.к. это требование прописано в ATPCS/AAPCS с 2000 года (после введения ARMv5).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Gcc не в курсе? Или кто делает lds файлы.. честно даже не знаю. Ну нет там аллигн8 (насколько помню), с телефона пишу, не посмотреть

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Итого в линкер файлах того же gcc мина лежит? Там везде стек а аллигн4 сегментах.

Мина. Но такая, что вряд ли когда рванет.

 

И еще тупой вопрос. Сегменты с аллигнами это ведь для линкера. Компилятор вообще в курсе?

А как он может быть в курсе? Он просто считает, что стек выровнен на 2 слова.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...