Jump to content

    

Выделение места под стек и кучу в Си

6 минут назад, Forger сказал:

Это все есть в мануале

Для меня кеил не родной, до таких подробностей мануал не изучал, каюсь.

6 минут назад, Forger сказал:

на край порылся бы в исходниках стандартных библиотек под этот компилятор.

Мне кажется что-то в CMSIS должно быть, они же определяют компилятор. Но опять же, компилятор может с разной стандартной библиотекой или линкером использоваться, так что тип компилятора ни чего не даст.

Share this post


Link to post
Share on other sites
Just now, VladislavS said:

Для меня кеил не родной

Для меня - тоже. 

Но чтение мануалов - вполне "родное" ;)

 

 

Share this post


Link to post
Share on other sites
6 hours ago, VladislavS said:

Да кто ж тебя про GCC спрашивал то?

Можно подумать, большая разница!

Edited by Eddy_Em

Share this post


Link to post
Share on other sites
34 минуты назад, Eddy_Em сказал:

Можно подумать, большая разница!

Представь себе.

Share this post


Link to post
Share on other sites
13 hours ago, haker_fox said:

Этим линкер занимается, читайте информацию про него.

Читал. Там нет ничего про __heap_limit, __stack_base и пр. Попробуйте сами. Например тут.

13 hours ago, aaarrr said:

А в чем смысл, можете пояснить?

Просто стало интересно. Почему нельзя самому определить массивы нужных размеров, разместить их в памяти по нужному тебе адресу директивами типа __attribute__((at(address))), занести конечный адрес массива стека в таблицу векторов и быть счастливым.

Потом возникли вопросы, а нужно ли как-то сообщить о границах стека и кучи компилятору/линкеру. Стал искать, что значат магические слова __heap_limit, __stack_base и пр. из ассемблерного стартапа. К своему удивлению, не нашел их упоминания ни в описании компилятора, ни линкера. Поиском нашел их в совершенно неожиданных местах тут

Но вопросы остались. Почему их надо объявлять именно в ассемблерных файлах или в ассемблерных вставках? Чем их объявление через #define в C/C++ файле хуже, чем через EQU в ассемблерном?

 

12 hours ago, aaarrr said:

Назначение секций линкером никак не помешает использовать их повторно в "настоящей" куче.

Чем "настоящая" куча отличается от "ненастоящей"? Я думал, что куча - она одна для всего. Все используют её. И я в своём коде, и все стандартные и нестандартные функции. Как стек - он ведь один для всех.

7 hours ago, Forger said:

Это все есть в мануале, оттуда и заимствовано.

Вот почему в ассемблерном файле всё просто, а в С/С++ так сложно? Я надеялся обойтись четырьмя дефайнами (адреса размещения и размеры стека и кучи) и двумя массивами (под стек и под кучу).

Share this post


Link to post
Share on other sites
12 minutes ago, Darth Vader said:

Вот почему в ассемблерном файле всё просто, а в С/С++ так сложно?

Кому как :dirol:

 

 

 

Share this post


Link to post
Share on other sites
26 minutes ago, Darth Vader said:

Чем их объявление через #define в C/C++ файле хуже, чем через EQU в ассемблерном?

Ничем: ни то, ни другое линкер не увидит, т.к. #define и EQU обрабатываются соответствующими препроцессорами.

Если заметили, линкер оперирует символами, задающими начало и конец региона. И если в ассемблере с этим проблем нет, то в C можно получить только первый из них.

 

28 minutes ago, Darth Vader said:

Чем "настоящая" куча отличается от "ненастоящей"? Я думал, что куча - она одна для всего. Все используют её. И я в своём коде, и все стандартные и нестандартные функции. Как стек - он ведь один для всех.

Куч может быть сколь угодно много: захотели использовать свой специфический менеджер памяти - выделили ему персональный кусок памяти под кучу.

Да и со стеком все не так однозначно, например, у каждой задачи может быть свой стек.

 

Share this post


Link to post
Share on other sites
59 minutes ago, aaarrr said:

у каждой задачи может быть свой стек.

"может быть" подразумевает, что у нескольких задач может быть общий стек? :scratch_one-s_head:

Share this post


Link to post
Share on other sites
2 часа назад, Darth Vader сказал:

Как стек - он ведь один для всех.

Такие заявления возникают только от незнания...

1 час назад, aaarrr сказал:

И если в ассемблере с этим проблем нет, то в C можно получить только первый из них.

В кейл - не знаю, но в IAR есть __section_begin()/__section_end()/__section_size().

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

В кейл - не знаю

На предыдущей странице я привел полностью рабочий кусок как раз в Keil, там все есть для повторения.  Почему народ не читает, непонятно :beee:

У меня задача стояла вообще не трогать скрипт линкера и сделать библиотечный стартап с расширяемым юзером стеком и сторонним менеджером кучи, отказавшись от штатного asm стартап файла. 

 

Share this post


Link to post
Share on other sites
4 hours ago, Darth Vader said:

Я думал, что куча - она одна для всего.

Не, куч может быть много. Например, LWIP-стек использует свою кучу для увеличения быстродействия. Хотя, в настройках можно указать и использовать любую другую.

4 hours ago, Darth Vader said:

Попробуйте сами.

Чессговоря так и не понял, что вы хотите изначально сделать. Я всегда думал, что в наибольшем количестве случаев достаточно пойти стандартным путём: выделить место под стек и кучу в скрипте линкера. При этом кучу может использовать как "стандартная" библиотека, так и своя. Куч и стеков может быть несколько. Но в любом случае всё распределение памяти через линкер. Может быть я не до конца понял. Попробуйте ещё раз объяснить, что нужно вам)

Share this post


Link to post
Share on other sites
3 hours ago, haker_fox said:

Попробуйте ещё раз объяснить, что нужно вам)

На первом этапе я хотел полностью повторить ассемблерный стартап в части резервирования места под кучу и стек но на С/С++. Т.е. объявить дефайнами размеры стека и кучи, объявить 2 массива соответствующих размеров. Один резервирует память под стек, второй под кучу. На втором добавить ещё пару дефайнов - адреса размещения стека и кучи в памяти и атрибуты __attribute__((at(address))) для масивов, чтобы поместить их в нужные мне места. Вот, собственно, вся задача.

А потом возник вопрос, а не следует ли как-то дополнительно сообщить компилятору/линкеру об адресах размещения и размерах областей стека и кучи? Если этого не сделать, то где компилятор выделит память под объект, встретив в коде malloc() или new() ? 

В конечном итоге полностью отказаться от ассемблерного стартапа, заменив его на С\С++ стартап.

Share this post


Link to post
Share on other sites
7 hours ago, Forger said:

"может быть" подразумевает, что у нескольких задач может быть общий стек? :scratch_one-s_head:

Разумеется :yes3:

Share this post


Link to post
Share on other sites
32 минуты назад, Darth Vader сказал:

В конечном итоге полностью отказаться от ассемблерного стартапа, заменив его на С\С++ стартап.

А зачем, кстати? Я вот одни и те же исходники разными компиляторами собираю, а вам зачем?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now