Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

STM32 keil где находятся глобальные переменные, стек, куча.

Пн май 06, 2013 14:10:41

Здравствуйте программируя под STM32f10x у меня возник вопрос как выделяется (откуда) память под глобальные, локальные переменные.
1. Как я понимаю под локальные переменные память выделяется в стеке. А вот что происходит с глобальными? выделяется в стеке или куче или сегменте данных. подкинте инфу.
2. Как просмотреть сколько памяти выделяется под код и под переменные в (симуляторе) keil 4. не происходит ли переполнение кучи или стека.
В своей прошивке я использую структуру объявленную как глобальная переменная размером 4168 байт всего на мк (озу SRAM) 20 килобайт памяти.
Под стек или кучу не знаю сколько выделяется и где это указывается???

Re: STM32 keil где находятся глобальные переменные, стек, ку

Пн май 06, 2013 14:41:22

Я так думаю стек не предназначен для хранения переменных,этот участок ОЗУ предназначен для временного хранения промежуточных значений работы функций.Да и доступ от туда не произвольный,а типа стопки тарелок,а взять можно только сверху.А по поводу кучи,если не использовать функции работы с памятью(типа memset,memcpy,memmove),то её можно вообще установить в 0x00.

Re: STM32 keil где находятся глобальные переменные, стек, ку

Пн май 06, 2013 18:13:53

Vov123 писал(а):Я так думаю стек не предназначен для хранения переменных,этот участок ОЗУ предназначен для временного хранения промежуточных значений работы функций.
промежуточные значения, не что иное, как локальные переменные
Vov123 писал(а):Да и доступ от туда не произвольный,а типа стопки тарелок,а взять можно только сверху.
.. доступ то произвольный, только поменяв в стеке что-нибудь "лишнее", программу легко можно отправить в "нокаут"
hovercraft писал(а):А вот что происходит с глобальными? выделяется в стеке или куче или сегменте данных. подкинте инфу.
... в отладчике все прекрасно видно ... размер и расположение задаются в свойствах проекта (вкладка Target)

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 10:47:43

The Cortex-M3 processor automatically pushes registers R0–R3, R12, LR, PSR, and PC in the stack at interrupt entry and pops them back at interrupt exit....
....The common use of a stack is to save register contents before some data processing and then restore those contents from the stack after the processing task is done.
Стек используется для сохранения контекста программы при обработке прерываний(обеспечивается ядром) и вызове функций(обеспечивается компилятором или вручную в случае ассемблера)
Стек не используется для локальных переменных. Для них используется свободные регистры из банка регистров общего назначения и свободное ОЗУ микроконтроллера.

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 11:06:08

ibiza11 писал(а):Стек не используется для локальных переменных. Для них используется свободные регистры из банка регистров общего назначения и свободное ОЗУ микроконтроллера.
не так категорично :) - стек можно использовать как угодно ...
Код:
      push {lr,r4,r5,r6}
      ; stack frame
      sub   sp,#16 ; выделяем буфер
   ........
      add   sp,#16 ; возврат в исходное состояние
      pop {lr,r4,r5,r6}
      bx   lr

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 11:19:50

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

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 11:34:31

Vov123 писал(а):ТС,я так понял собрался в стеке хранить переменные постоянно
...не знаю, почему Вы так решили
hovercraft писал(а):1. Как я понимаю под локальные переменные память выделяется в стеке.
стек удобно применять, как локальный буфер ( в РС например (i808x-...), есть регистр BP специально для этого ... у ARM регистры более универсальны)

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 11:42:37

Ну,что-ж,может быть я не сильно оторвался от 8-разрядников.

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 12:10:33

...конечно аппаратные возможности накладывают свой "отпечаток" , но в целом механизм использования стека универсален - пример для AVR (CV AVR)

создаем "бесполезную" ф-цию funcion_X
Код:
void funcion_X(char x){
      char buff[16];
      buff[0]=5;
      buff[10]=buff[0]+x;     
}
и где-нибудь в main делаем вызов ...
Код:
main(){
....
    funcion_X(4);
после компиляции смотрим в *.asm-файл
Код:
;      60 void funcion_X(char x){
_funcion_X:
;      61       char buff[16];
;      62       buff[0]=5;
   SBIW R28,16
;   x -> Y+16
;   buff -> Y+0
   LDI  R30,LOW(5)
   ST   Y,R30
;      63       buff[10]=buff[0]+x;
   LDD  R30,Y+16
   LD   R26,Y
   ADD  R30,R26
   STD  Y+10,R30
;      64 }
   ADIW R28,17
   RET
SBIW R28,16 - не что иное как выделение буфера в стеке (r29:28==Y-регистр)

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 12:26:09

ChipKiller писал(а):не так категорично - стек можно использовать как угодно ...
Перечитайте стартовое сообщение и поймете, что автор задает вопрос не по ассемблеру. А так да, что угодно можно творить со стеком. Только вопрос не в этом заключался. Автор не знает куда компилятор засунет его глобальную структуру и поэтому спрашивает сколько нужно кучи и стека.
ChipKiller писал(а):SBIW R28,16 - не что иное как выделение буфера в стеке (r29:28==Y-регистр)
стек тут нипричем. здесь идет выделение памяти в ОЗУ, возможно в куче. Откуда вы знаете куда указывает Y?
Стек, как уже было упомянуто работает по принципу стопки тарелок, с командами push и pop . А у Вас в примере просто относительная адресация.

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 12:58:43

ibiza11 писал(а):стек тут нипричем. здесь идет выделение памяти в ОЗУ
ChipKiller писал(а):SBIW R28,16 - не что иное как выделение буфера в стеке (r29:28==Y-регистр)
... разумеется - аппаратный стек (или стек вызовов) хранится в SP, поэтому я и писал .
ChipKiller писал(а):.конечно аппаратные возможности накладывают свой "отпечаток"
... и речь шла о стеке данных
ibiza11 писал(а):Стек, как уже было упомянуто работает по принципу стопки тарелок, с командами push и pop . А у Вас в примере просто относительная адресация.
на стек влияют не только push и pop, но и команды вызова/возврата.
На счет относительной адресации - именно поэтому и провел аналогию с 8086. В ARM можно написать
Код:
str r4,[sp,#4]
- ведь sp регистр
ibiza11 писал(а):автор задает вопрос не по ассемблеру....
... в том то и беда, что многие пытаются освоить ARM не понимая принципов.....

ЗЫ. ... короче тема для флейма .... оно мне не надо.....

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 13:40:12

Вот именно, что не надо...
А стек и куча настраивается в .S файле...

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 13:44:05

Могу Вам подкинуть определение слова "стек" (stack). Но думаю Вы и так знаете, учитывая Вашу осведомленность в нескольких архитектурах, что Вас кардинально отличает от местных проAVRславных и PICудеев. В Вашем примере с AVR неприменимо слово "стек" исходя из определения, поэтому я и взбунтовался :)
Надеюсь ТС понял что к чему)

Re: STM32 keil где находятся глобальные переменные, стек, ку

Вт май 07, 2013 15:16:42

Может кому-то будет полезно: http://www.opennet.ru/base/dev/stack_intro.txt.html

Re: STM32 keil где находятся глобальные переменные, стек, ку

Ср май 08, 2013 15:41:40

Целую страницу написали, а по вопросу так ничего и не ответили.

1. Память под локальные переменные если и выделяется, то в стеке. Компилятор может это дело оптимизировать и не выделять под них память, работая только с регистрами.

2. Все глобальные переменные, если не указано явно, засовываются в несколько разных секций в зависимости от некоторых факторов. Подробнее можно почитать в документах от ARM.

3. Для кучи и стека ты сам, в startup.s (обычно), объявляешь секции выбранного размера. Одну общую, или две разные. Далее, в этом же startup.s (обычно), ты должен реализовать чудо-функцию __user_setup_stackheap или __user_initial_stackheap, с помощью которой компилятор узнает где куча, а где стек. Подробнее можно почитать в документах от ARM.

4. Все эти секции ты размещаешь где твоей душе угодно в специальном scatter-файле. Подробнее можно почитать понятно где.

5. Для того, чтобы посмотреть, как, в итоге, компоновщик все это разместил, есть специальный map-файл. В настройках проекта можешь включить его генерацию.

Re: STM32 keil где находятся глобальные переменные, стек, ку

Чт май 09, 2013 15:59:40

menzoda писал(а):1. Память под локальные переменные если и выделяется, то в стеке. Компилятор может это дело оптимизировать и не выделять под них память, работая только с регистрами.

Неверно. Стек используется в первую голову для временного хранения адреса возврата, критичных для корректного возврата регистров и ВОЗМОЖНО для передачи параметров и результата в процедуры/функции и обратно. Передача и хранение - это две большие разницы. ibiza11 прав на все 146%.
Можно организовать еще и свой стек для хранения данных, а можно и просто через указатели шарашить. Нехай компилятор сам разбирается, где константа, а где переменная...
Рассмотрим принстонскую (она же Неймана, во всех персоналках) и гарвардскую (которая в МК) архитектуры. Соответственно - в Гарвардской архитектуре - два типа памяти: одна хранит программу, другая - данные. Ну и дальше понеслась проблема компилятора хранить переменные (данные) либо в регистрах (запихивая по необходимости в стек), либо в ОЗУ, а программу хранить во флеш-памяти. С соответствующими архитектурными тонкостями, когда адресация флеш, регистров и ОЗУ может быть как одинаковой, так и разной. У принстона проблем меньше. Можно даже самомодифицирующуюся программу написать.
(Ну 2х2=4. Банально. Это я просто откуда ноги у проблемы растут нарисовал).
Хохму про запуск программы из ОЗУ знаю. И что у кипарисов это - единственный способ - тоже.
Где что хранится - по карте памяти посмотреть можно, но особого смысла нет. Достаточно ключевыми словами указать, что именно является переменными, а дальше нехай компилятор сам думает, что он будет хранить и передавать в регистрах, что в стеке, а что - в ОЗУ. Его этому специально учили :).
По прочим пунктам от menzoda и прочих что-то корректировать/предлагать и т.п. не буду. Каждый сам выбирает свой способ работы с переменными, как ему удобнее. Можно полистать примеры в том же кейле и посмотреть.
Да, я по простоте душевной считаю, что для 32-разрядных МК применять ассемблер - мазохизм. Но это МОЙ выбор. Кто хочет - пусть хоть в кодах пишет, мешать и спорить не буду.

Re: STM32 keil где находятся глобальные переменные, стек, ку

Чт май 09, 2013 16:29:33

Ну а где тогда сидят локальные переменные? Вот возьму и напишу несколько функций, в каждой по N-надцать локальных переменных. Где будет выделяться под них память, если не в стеке? Что за ерунда.

Вот пример.

Код:
int foo (int val)
{
   int i, s;
   int array[20];
   
   s = 0;
   for (i = 0; i < 20; i++)
      array[i] = val;
   for (i = 0; i < 20; i++)
      s += array[i];
   
   return s;
}

Эта функция скомпилировалась в это:

||foo|| PROC
        [b]SUB      sp,sp,#0x50[/b]
        MOV      r3,r0
        MOV      r0,#0
        MOV      r1,#0
        MOV      r2,sp
|L1.20|
        STR      r3,[r2,r1,LSL #2]
        ADD      r1,r1,#1
        ...

То, что выделенно жирным есть выделение памяти под локальный массив в стеке. Для переменных он не стал выделять память, ибо их можно хранить в регистрах, но можно сделать так:

int foo (int val)
{
   [b]volatile[/b] int i, s;
   int array[20];
...

После компиляции это станет следующим:

||foo|| PROC
        [b]SUB      sp,sp,#0x58[/b]
        MOV      r3,#0
        STR      r3,[[b]sp[/b],#0x50]
        STR      r3,[[b]sp[/b],#0x54]
        MOV      r1,[b]sp[/b]
|L1.20|
        LDR      r2,[[b]sp[/b],#0x54]
        STR      r0,[r1,r2,LSL #2]
        LDR      r2,[[b]sp[/b],#0x54]
        ADD      r2,r2,#1
        ...

Теперь мы заставили его выделить под переменные память в стеке.



Что не так то? Повторяю - где ему еще выделять память под локальные переменные, как не в стеке??????

Re: STM32 keil где находятся глобальные переменные, стек, ку

Чт май 09, 2013 16:38:10

ChipKiller писал(а):... короче тема для флейма ....
... модераторы похороните топик - больше срача, чем пользы ......

Re: STM32 keil где находятся глобальные переменные, стек, ку

Чт май 09, 2013 17:33:57

menzoda писал(а):Ну а где тогда сидят локальные переменные?

Когда понадобится ключевое слово volatile - узнаешь. Скорее всего. Если захочешь...

Re: STM32 keil где находятся глобальные переменные, стек, ку

Чт май 09, 2013 18:57:29

ChipKiller писал(а):
ChipKiller писал(а):... короче тема для флейма ....
... модераторы похороните топик - больше срача, чем пользы ......
И это правильно, как говаривал разрушитель СССР.. :)
Даже не хотят вспомнить два простых словосочетания - стек данных и стек возврата. Свалили все в кучу. Компилятор умнее их оказался, и пользуется двумя стеками.
Практически все грамотные компилеры позволяют регулировать их соотношения и размеры.
Изображение
Ответить