Стік викликів починається знизу або вгорі?


11

Стек - це те, що збирається знизу вгору.

Отже, стек викликів додає нові елементи в стек, коли викликаються функції, при цьому елементи, вилучені зі стека, оскільки кожна функція закінчується, поки стек не порожній, а потім програма закінчується.

Якщо вищесказане правильно, чому люди посилаються на керування переміщенням "вгору" стека викликів? Безумовно, управління рухається вниз по стеку викликів, поки не досягне нижньої частини.


Коли викликається функція, елемент додається у верхню частину стека, а керування передається цій функції. Звідси елемент управління переміщується від основного елемента в стеку до верхнього елемента - вгору.
treecoder

1
@greengit: вираз "до стека викликів" використовується за винятком, коли управління насправді рухається в зворотному напрямку.
Майкл Боргвардт

@MichaelBorgwardt: Ви маєте рацію.
деревокодер

1
@MichaelBorgwardt: Я бачив вираз "помилки рухаються вгору до стека викликів". Звичайно, це неправильно.
CJ7

Відповіді:


9

Існує дві можливі причини такого використання:

  • У контексті винятків керування переходить до функції / методу виклику, і ця ієрархія викликів зазвичай візуалізується головним методом зверху та викликами методів, утворюючи ієрархію вниз, зі зниженням рівня абстракцій. У цій ієрархії виняток рухається вгору.

  • Фактичний стек програми в звичайному додатку x86 інвертується, тобто він зростає вниз. Інструкції машинного коду PUSH / PUSHW / PUSHD зменшують покажчик стека. Інші архітектури можуть поділяти цю модель.


Хіба ідея зверху вниз не суперечить повсякденній концепції "стека" - це купа елементів, що починаються внизу?
CJ7

@CraigJ: таким є факт, що біти кожного байту вмісту стеку будуть фізично зберігатися в окремих чіпах. Кого хвилює?
Майкл Боргвардт

1

Все залежить від визначення слів; що саме ви маєте на увазі під цим словом "верх" і "знизу", а також про реалізацію операційної системи або архітектури комп'ютера.

Я пам'ятаю наступне давно, коли я програмував на Commodore 64. Пам'ять між адресою $ 0800 (2048) та $ 9FFF (40959) була зарезервована для програм BASIC. Код вашої програми BASIC зберігався починаючи з нижньої адреси ($ 0800, зростаючи звідти). Стек для зберігання змінних та зворотних адрес підпрограм починається у верхній частині ($ 9FFF) цього діапазону і зростає до нижчих адрес. Тож у цьому контексті було логічно бачити стек як зростаючий вниз, і коли ви повертаєтеся з підпрограми, стек кадру підпрограми був відкинутий, збільшуючи покажчик стека, так що ви могли сказати, що ви "переміщуєте стек", коли повернення з підпрограми.

Я не знаю, як це працює в сучасних версіях, наприклад, для процесорів Windows або Intel x86. Можливо, стек працює навпаки, тобто зростає від нижчих до більш високих адрес. У такому випадку ви, мабуть, вживатимете слова "вгорі", "знизу" та "вгору", "вниз" саме навпаки.


0

Для виклику такої функції, як foo (6, x + 1) ...

  1. Оцініть фактичні вирази параметрів, такі як x + 1, в контексті абонента.
  2. Виділіть пам’ять для місцевих жителів foo (), натиснувши відповідний «локальний блок» пам’яті на «стек виклику» для виконання, призначений для цього. Для параметрів, але не для локальних змінних, зберігайте значення з кроку (1) у відповідному слоті в локальному блоці foo ().
  3. Збережіть поточну адресу виконавця (його "повернення адреси") і переключіть виконання на foo ().
  4. foo () виконує зі своїм локальним блоком, зручно доступним в кінці стека викликів.
  5. Коли foo () закінчений, він виходить, вискакуючи своїх локальних жителів зі стека та "повертається" до абонента, використовуючи раніше збережену адресу повернення. Тепер місцеві жителі абонента знаходяться на кінці стеку, і він може відновити виконання.

Довідка:

http://cslibrary.stanford.edu/102/PointersAndMemory.pdf (p15)


Зауважте, що це дуже специфічно для конвенції про закликання. Існують умовні умови виклику, які дозволяють абоненту прибиратись, більшість використовує хоча б деякі регістри тощо.

0

Якщо ви уявляєте стек як річ "знизу вгору", як циліндр з тенісними м'ячами в ньому при нормальній гравітаційній реальності, тоді керування рухається вгору по стопі, як називаються функції. Коли функції завершені, елемент управління переміщається вниз по стеку.

Якщо ви концептуалізуєте стек як предмет зверху вниз, як той же циліндр тенісних м'ячів, але з перевернутою силою тяжіння, тоді управління рухається вниз по стопі, як викликаються функції, і вгору до стека, коли функції завершені.

Це обидві просто моделі в вашій голові і по суті є абсолютно довільними. Якщо ви хочете, ви можете концептуалізувати це як бічну сторону, але у вас можуть виникнути проблеми у спілкуванні з людьми. Я особисто думаю, що якщо A викликає B і B називає C, то C - це нижня частина стека (перевернута гравітаційна реальність), і якщо виняток виникає в C, ви хочете перекинути цей виняток "до" А. Я думаю, що це може бути більш поширене використання мови, оскільки відчувається, що C - в глибині душі, а A - це верх. Перша функція більш інтуїтивно зрозуміла для мене, і функції стають все глибшими під час кожного дзвінка.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.