Как вещи хранятся в стеке? - PullRequest
       55

Как вещи хранятся в стеке?

1 голос
/ 29 октября 2009

Итак, я изучал ассемблер и пришел к теме стека, где хранятся локальные, статические и глобальные переменные и прочее.

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

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

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

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

Ответы [ 7 ]

8 голосов
/ 29 октября 2009

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

68000 CPU stack
(источник: eventhelix.com )

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

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

3 голосов
/ 29 октября 2009

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

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

Понять стек

Направление роста стека

2 голосов
/ 29 октября 2009

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

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

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

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

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

2 голосов
/ 29 октября 2009

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

1 голос
/ 29 октября 2009

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

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

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

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

0 голосов
/ 29 октября 2009

«Вершина» стека не имеет ничего общего с тем, как стек размещается в памяти.

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

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

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

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

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

0 голосов
/ 29 октября 2009

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

...