Я знаю, что в архитектуре я лично знаком с (x86, 6502, и т.д.), стек обычно растет вниз (т.е. каждый объект, продвинутый на результаты стека в постепенно уменьшенном SP, не увеличенный).
Я задаюсь вопросом об историческом объяснении для этого. Я знаю, что в объединенном адресном пространстве, удобно запуститься, стек на противоположном конце сегмента данных (говорят), таким образом, существует только проблема, если эти две стороны сталкиваются в середине. Но почему стек традиционно получает верхнюю часть? Особенно учитывая то, как это - противоположность "концептуальной" модели?
(И обратите внимание, что в 6 502 архитектуре, стек также растет вниз, даже при том, что это ограничено к единственной 256-байтовой странице, и этот выбор направления кажется произвольным.)
Как к историческому обоснованию, я не могу сказать наверняка (потому что я их не создавал). Мои мыслей по этому вопросу - это то, что ранние процессоры получили свой первоначальный счетчик программы, установленный на 0, и это было естественное желание начать стек на другом конце и расти вниз, поскольку их код естественным образом растет вверх.
Кроме того, обратите внимание, что эта настройка счетчика программы на 0 на сбросе не является случай для всех ранних процессоров. Например, Motorola 6809 будет получать счетчик программы от адресов
0xFFFE / F
, чтобы вы могли начать работать в произвольном месте, в зависимости от того, что поставлялось по этому адресу (обычно, но ни в коем случае не ограничивается, ПЗУ).
Одним из первых вещей, которые некоторые исторические системы будут делать, будут просканировать память сверху, пока она не нашла бы место, которое будет прочитать то же значение, так что он будет знать фактическую установленную ОЗУ (например, a Z80 с 64K адресное пространство не обязательно не обязательно было 64 к или оперативной памяти, на самом деле 64К было бы в первые дни . После того, как он нашел верхний фактический адрес, он установил бы указатель стека соответствующим образом и затем начать вызов подпрограмма. Это сканирование, как правило, будет выполняться запуск CPU в ROM как часть запуска.
Что касается роста стека, не все они растут вниз, см. Этот ответ для деталей.
Я не уверен, но кое-что программировал для VAX/VMS еще в те времена. Кажется, я помню, как одна часть памяти (куча??) шла вверх, а стек - вниз. Когда они встретились, у тебя не было памяти.
Одной из возможных причин может быть то, что это упрощает выравнивание. Если вы помещаете на стек локальную переменную, которая должна быть расположена на границе 4 байт, вы можете просто вычесть размер объекта из указателя стека, а затем обнулить два нижних бита, чтобы получить правильно выровненный адрес. Если стек вырастет вверх, то обеспечение выравнивания станет несколько хитрее.
Одно из хороших объяснений, которое я слышал, состояло в том, что некоторые машины в прошлом могли иметь только неподписанные смещения, так что вам бы хотелось, чтобы стек рос вниз, чтобы вы могли ударить по местным жителям, не теряя при этом дополнительных инструкций, чтобы подделать отрицательное смещение.
Это приведет к бесконечному циклу. См. MSDN
-121--2434856-IIRC стека растет вниз, потому что кучи растут вверх. Это мог быть другой путь вокруг.
-121--797177-Я считаю, что это чисто проектное решение. Не все они растут вниз - см. этот поток SO для хорошего обсуждения направления роста стека на различных архитектурах.
IIRC Стек растет вниз, потому что куча растет вверх. Это могло быть наоборот.