2009-10-29 9 views
1

Итак, я изучал сборку и приходил к теме стека, сохраняя локальную, статическую и глобальную переменную и прочее.Как вещи хранятся в стеке?

Но мне трудно представить его в голове.

Нижняя часть памяти, но сверху стека: S whaa ??

То, что меня смутило, каждый раз, когда что-то нажимает (ed) в стек, вычитается указатель стека. Не следует добавить к этому.

Я имею в виду, что я получаю код, но его трудно не знать, что происходит на самом деле.

ответ

7

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

68000 CPU stack http://www.eventhelix.com/RealtimeMantra/Basics/CToAss1.gif

память адреса увеличиваться по мере продвижения вниз, но когда вы хотите, чтобы нажмите что-то на наверху из стека вы поместите его на вверху диаграммы (по нижнему адресу).

(Диаграмма можно найти на EventHelix.com.)

+0

+1 для иллюстрации. – outis

+0

Это потрясающе, спасибо за диаграмму – saint

+0

, в какой точке будет стек ... переполнение? – Moak

2

Подумайте об этом как о деталях реализации. На многих архитектурах, когда вы нажимаете что-то в стек, указатель стека вычитается, поэтому стек растет вниз (на меньшие адреса). Это все.

2

Причина, по которой они делают это, потому что стек имеет один и тот же кусок памяти с кучей. Куча растет сверху (низкий адрес) до нижнего (более высокий номер адреса), а стек растет снизу (высокий номер адреса) вверх (нижний).

Это делается для того, чтобы не требовалось предсказывать объем памяти дважды (один для кучи и другой для стека).

00000000 HEAP---- 
00000001 |||||||| 
00000002 vvvvvvvv 

FFFFFFFD ^^^^^^^^ 
FFFFFFFE |||||||| 
FFFFFFFF Stack 

Надеюсь, это поможет.

1

Причина для декрементации SP заключается в том, что (*) стек добавляется к «снизу» (относительно места памяти). Было бы немного, если бы у вас было «список дел». Вы запустите его в верхней части страницы, и вместо того, чтобы отмечать отдельные вещи случайно в списке (как это обычно бывает), вы только начинаете и завершаете работу, которая наиболее удалена по странице.

Причина этого использования памяти сверху (то есть из более высоких адресов) для стека заключается в том, что она позволяет другое важное хранилище памяти, куча будет расти в другом направлении (по крайней мере, это имеет место в некоторые модели памяти). Продолжая аналог «делать список», теперь вы также пишете еще один список, скажем, список покупок, который находится внизу страницы. Тем не менее, этот список является кучей, вы позволили бы себе стереть вещи из него в случайных местах, когда вы проходите через магазин, а также повторно используете пространство, оставшееся от некоторых стираемых линий.

Теперь, рискуя добавить больше материала для путаницы, еще одним важным элементом управления стеком является концепция stack frame, что является удобным способом хранения параметров для функции и локальных переменных, которые соответствуют «общий контекст» вызовов вложенных функций.

(*) на многих CPU, то есть. Как отметил Пьер, некоторые процессоры работают со стеком, которые перемещают SP «вверх» (увеличивают его), когда на него нажимают вещи.

3

То, что меня смутило, каждый раз, когда что-то нажимает (ed) в стек, вычеркивается указатель стека. Не следует добавить к этому.

Это может быть. Это зависит от того, растет ли стек вверх или вниз.

Understand the stack

Stack grow direction

+0

Очень полезные ссылки, спасибо! – saint

0

стек растет вниз, куча растет вверх, таким образом, вы не должны решить, сколько для каждого. На самом деле все сложнее, чем сейчас, но x86 и другие имеют машинные операции с этим встроенным допущением. В любом случае это не имеет значения, машина добавляет ands вычитается одинаково хорошо.

0

«Верх» стека не имеет никакого отношения к тому, как стек выкладывается в памяти.

Это структура данных. Аналогом «стека» является концептуальная модель, тот факт, что она растет вверх или вниз в пространстве памяти, является просто детальностью реализации. Heck, тот факт, что он использует непрерывный блок памяти, является просто деталью реализации; вы можете очень хорошо иметь стек, где предметы разбросаны повсюду, например, если вы реализуете его как связанный список.

Это даже не реальный стек: рассмотрите, например, что, хотя в учебнике написано, что это «последний в первом», вы можете на самом деле изменить элементы в середине стека.

Что вам нужно реализовать стек является:

  • способ указать на каждый кадр/элемент стека
  • образом, чтобы указать на последний вставленный элемент стека (так называемый стек сверху)
  • образом, чтобы получить к предыдущему элементу
  • образом, чтобы вставить элемент в конце/верхнего
  • способ удаления элемента из конца/сверху, так что его предыдущий элемент становится новым последним/верхний элемент.

Как выглядит макет памяти, не имеет никакого отношения ни к одному из них.