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

Почему в small-модели стеки находятся снизу?

Почему в small-модели стеки находятся снизу и как это исправить?

 

Работая с ATtiny2313 я уже привыкла к тому, что стеки (CSTACK и RSTACK) находятся сверху (в старших адресах). Это было очень удобно тем, что в программе можно было явно установить указатель RSTACK'а на самый верх, тем самым, задействуя всю неиспользованную память под стеки. Вручную же рассчитывать размеры стеков крайне неудобно, т.к. CSTACK запрашивают в байтах, а RSTACK в словах. А я не арифмометр, чтобы подбирать эти значения так, чтобы они вписались во весь объем памяти. Тем более что такую операцию мне пришлось бы выполнять каждый раз, когда бы я заводила или удаляла какую-нибудь переменную или изменяла размеры массива. А так, устанавливаешь указатель на вершину памяти и никакой тебе головной боли.

Однако перейдя со временем на МК с большим объемом ОЗУ, пришлось перейти и на модель памяти small. И тут меня ждало неприятное известие о том, что теперь стеки находятся внизу, за ними данные, а пустое пространство сверху. Теперь его уже никак нельзя использовать, кроме как вручную каждый раз изменять размеры стеков в проекте.

В таком расположении стеков я ничуть не виновата - IAR так делает сам. Вот посмотрите на контрольный тест для ATmega8. Этот МК выбран только потому, что допускает обе модели памяти: как tiny, так small. Пишу простейшую программу, содержащую массив данных Buffer, и компилирую ОДИН И ТОТ ЖЕ ПРОЕКТ на tiny и small моделях, переключая в проекте ТОЛЬКО тип модели и не трогая ничего остального.

 

unsigned char Buffer[70];

C_task main( void )
{
  Buffer[0] = 0;
}

В модели tiny получаю:

 

SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
TINY_I               DATA               00000060                     dse    0
TINY_Z               DATA          00000060 - 000000A5          46   rel    0
CSTACK               DATA          000000A6 - 000000B9          14   dse    0
RSTACK               DATA          000000BA - 000000C9          10   dse    0

А в модели small вот это:

 

SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
CSTACK               DATA          00000060 - 00000073          14   dse    0
RSTACK               DATA          00000074 - 00000083          10   dse    0
NEAR_I               DATA               00000084                     dse    0
NEAR_Z               DATA          00000084 - 000000C9          46   rel    0

Абсолютно та же самая ситуация со small-моделью во всех остальных моделях МК (проверяла еще и на AT90USB647).

 

Мой вопрос: Какими соображениями обусловлено такое распределение памяти в small-модели? Можно ли как-то изменить такое распределение памяти и заставить компилятор размещать данные ниже стеков?

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

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


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

Разница в .xcl файлах.

Линкер размещает сегменты в памяти в том порядке, в каком они перечислены в директивах -Z(DATA).

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


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

Xenia, Вы очевидно полагаетесь на конфигурирование Вашего проекта через диалог (General Options->Target->System configuration->Configure system using dialog).

Если хотите держать всё под контролем, конфигурируйте систему через .xcl файл.

Нужный файл нужно скопировать в свой проект из папки /avr/config установленного продукта и указать на него в настройках Linker->Config->Linker command file и править его размещая сегменты как душе угодно.

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


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

Разница в .xcl файлах.

Линкер размещает сегменты в памяти в том порядке, в каком они перечислены в директивах -Z(DATA).

 

Это не так!

Для ATmega8 по умолчанию имеются два файла для конфигурации линкера: lnkm8t.xcl (для tiny-модели) и lnkm8s.xcl (для small-модели). Смотрим конфигурацию для small-модели (файл lnkm8s.xcl):

 

/* Internal data memory */

-Z(DATA)TINY_I,TINY_Z,TINY_N=60-FF

-Z(DATA)NEAR_I,NEAR_Z=60-45F

-Z(DATA)RSTACK+_..X_RSTACK_SIZE=60-45F

-Z(DATA)CSTACK+_..X_CSTACK_SIZE=60-45F

-Z(DATA)HEAP+_..X_HEAP_SIZE=60-45F

-Z(DATA)IOSTREAM_N#60-45F

-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=60-45F

 

Как видим, стеки перечислены ПОСЛЕ данных, но, тем не менее, располагаются они в обратном порядке (RSTACK+CSTACK ниже чем NEAR_I+NEAR_Z). Примерно таже последовательность и в файле конфигурации tiny-модели. Если отбросить все то, что к делу не относится (хипы и иостримы), но порядок перечисления сегментов -Z(DATA) для обоих моделей использован одинаковый - память раньше стеков, но результат компиляции получается разный.

Ваше утверждение уже потому не может быть правдой, что в конфигурациях линкера строка RSTACK стоит раньше чем CSTACK, когда как каждому известно, что CSTACK всегда ниже RSTACK'а, т.к. первый растет вверх, а второй вниз.

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

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


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

RSTACK стоит раньше чем CSTACK, когда как каждому известно, что CSTACK всегда ниже RSTACK'а, т.к. первый растет вверх, а второй вниз.

Это с каких пор CSTACK вверх растет???

Вы листинг смотрели? Там видно сразу куда что растет.

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


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

Это с каких пор CSTACK вверх растет???

Вы листинг смотрели? Там видно сразу куда что растет.

В tiny-модели вроде бы CSTACK кверху рос. Впрочем, я не твердо в том уверена, поскольку старалась локальные переменные в функциях размещать в мусорных регистрах. Но в какую бы сторону ни рос стек, мой вопрос остается в силе. Я привела явные доказательства того, что в small-модели стеки организуются ниже данных. Об этом однозначно свидетельствует выдержка из map-файла, которую я привела в первом сообщении. Пока мой вопрос о причинах этого явления остается без ответа.

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

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


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

а вы свой XCL файл писали?

Что то у меня всегда сегменты шли в нужном мне порядке...

попробуйте их тогда в одной строчке перечислить! тогда точно в нужном порядке пойдут!

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


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

Проверил на версии 4.12.

Ещё интереснее, при установленой галке General Options->Target->Configure system using dialog(not in .XCL file) директивы размещения сегментов берутся из \avr\src\template\cfg1soim.xcl или \avr\src\template\cfg1toim.xcl.

 

А при снятой - из \avr\config\lnkm8s.xcl или \avr\config\lnkm8t.xcl.

Это видно в "шапке" в начале map-файла.

 

При снятии/установке галки положение сегментов меняется, но именно в соответствии с порядком следования -Z директив в этих файлах.

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


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

Пока мой вопрос о причинах этого явления остается без ответа.

Постараюсь ещё раз.

У Вас было два вопроса: о причинах и соображениях такого распределения и как сделать так как надо.

На первый вопрос Вам ответили, что расположение сегментов описано в xcl файлах. Из чего исходили IARовцы, располагая таким образом сегменты - одному Богу известно. Абсолютно однозначных причин на это нет.

Что касается второго вопроса, то в третьем посте я Вам уже говорил, что нужно сделать. Добавлю только, что если Вы хотите прижать стеки к потолку ОЗУ, то вместо символа "=" надо ставить "#"

-Z(DATA)RSTACK+_..X_RSTACK_SIZE#60-45F
-Z(DATA)CSTACK+_..X_CSTACK_SIZE#60-45F

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


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

Ещё интереснее, при установленой галке General Options->Target->Configure system using dialog(not in .XCL file) директивы размещения сегментов берутся из \avr\src\template\cfg1soim.xcl или \avr\src\template\cfg1toim.xcl.

А при снятой - из \avr\config\lnkm8s.xcl или \avr\config\lnkm8t.xcl.

Это видно в "шапке" в начале map-файла.

При снятии/установке галки положение сегментов меняется, но именно в соответствии с порядком следования -Z директив в этих файлах.

 

Огромное спасибо! Теперь мне стала абсолютно ясна причина, по которой у меня расстановка сегментов не соответствовала файлу конфигурации lnkm8s.xcl - компилятор брал его из другого файла cfg1soim.xcl, поскольку та галка у меня в проекте стояла.

Стало быть разница в укладке сегментов следует из содержимого файлов конфигурации cfg1soim.xcl и cfg1toim.xcl.

 

В модели tiny стеки выше tiny-данных:

 

-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE

-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE

-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE

-Z(DATA)IOSTREAM_N#_..X_SRAM_TBASE:+_..X_SRAM_TSIZE

-Z(DATA)TINY_HEAP+_..X_TINY_HEAP_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE

-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END

-Z(DATA)NEAR_I,NEAR_Z=_..X_SRAM_BASE-_..X_SRAM_END

-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END

-Z(DATA)NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END

 

А в модели small стеки ниже near-данных:

 

-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE

-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_CSTACK_BASE-_..X_CSTACK_END

-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END

-Z(DATA)IOSTREAM_N#_..X_SRAM_BASE-_..X_SRAM_END

-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END

-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END

-Z(DATA)NEAR_I,NEAR_Z,NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END

 

Еще раз спасибо за исчерпывающее разъяснение!

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

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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