Поведінка стека (зростання або зростання) залежить від бінарного інтерфейсу програми (ABI) і від того, як організований стек викликів (він же запис активації).
Протягом свого життя програма зобов'язана спілкуватися з іншими програмами, такими як ОС. ABI визначає, як програма може взаємодіяти з іншою програмою.
Стек для різних архітектур може зростати в будь-який спосіб, але для архітектури він буде послідовним. Перевірте це посилання на вікі. Але зростання стека визначається ABI цієї архітектури.
Наприклад, якщо ви берете MIPS ABI, стек дзвінків визначається, як показано нижче.
Давайте розглянемо, що функція 'fn1' викликає 'fn2'. Тепер кадр стека, як видно з 'fn2', є таким:
direction of | |
growth of +---------------------------------+
stack | Parameters passed by fn1(caller)|
from higher addr.| |
to lower addr. | Direction of growth is opposite |
| | to direction of stack growth |
| +---------------------------------+ <-- SP on entry to fn2
| | Return address from fn2(callee) |
V +---------------------------------+
| Callee saved registers being |
| used in the callee function |
+---------------------------------+
| Local variables of fn2 |
|(Direction of growth of frame is |
| same as direction of growth of |
| stack) |
+---------------------------------+
| Arguments to functions called |
| by fn2 |
+---------------------------------+ <- Current SP after stack
frame is allocated
Тепер ви можете бачити, як стек росте вниз. Отже, якщо змінні призначені локальному фрейму функції, адреси змінної насправді зростають вниз. Компілятор може приймати рішення про порядок змінних для розподілу пам'яті. (У вашому випадку це може бути або 'q' або 's', що спочатку виділяється пам'яттю стека. Але, як правило, компілятор розподіляє пам'ять стека відповідно до порядку оголошення змінних).
Але у випадку масивів виділення має лише один покажчик, і пам'ять, яку потрібно виділити, буде фактично вказана одним покажчиком. Пам'ять повинна бути суміжною для масиву. Отже, хоча стек росте вниз, для масивів стек росте.