Означает ли это, что базовый указатель или указатель стека фактически перемещаются вниз по адресам памяти, а не идут вверх? Почему это?
Да, push
инструкции уменьшают указатель стека и записывают в стек, в то время как pop
выполняют обратное чтение из стека и увеличивают указатель стека.
Это несколько исторично, поскольку для машин с ограниченной памятью стек размещался высоко и увеличивался вниз, а куча - низко и увеличивалась вверх. Существует только один пробел «свободной памяти» - между кучей и стеком, и этот пробел распределяется между собой, либо любой может вырасти в промежуток по мере необходимости. Таким образом, программе не хватает памяти только тогда, когда стек и куча сталкиваются, не оставляя свободной памяти.
Если стек и куча растут в одном и том же направлении, то есть два пробела, и стек действительно не может врасти в промежуток кучи (наоборот, это также проблематично).
Первоначально процессоры не имели специальных инструкций по обработке стека. Однако, поскольку поддержка аппаратного обеспечения была добавлена к оборудованию, она приобрела тенденцию к снижению, и процессоры все еще следуют этой схеме сегодня.
Можно утверждать, что на 64-битной машине достаточно адресного пространства, чтобы разрешить множественные промежутки - и, как доказательство, множественные промежутки обязательно имеют место, когда процесс имеет несколько потоков. Хотя это не является достаточной мотивацией для изменения ситуации, поскольку в случае систем с множеством разрывов направление роста, возможно, произвольно, поэтому традиции / совместимость перевешивают масштабы.
Вы должны были бы изменить инструкции по обработке стеки CPU для того , чтобы изменить направление стека, либо отказаться от использования выделенного толкая и выскакивают инструкции (например push
, pop
, call
, ret
и других).
Обратите внимание, что архитектура набора команд MIPS не имеет выделенного символа push
& pop
, поэтому практично увеличивать стек в любом направлении - вам все еще может потребоваться размещение памяти с одним зазором для однопоточного процесса, но можно увеличить стек вверх и кучу вниз. Однако, если вы это сделаете, для некоторого кода C varargs может потребоваться корректировка в передаче исходных или скрытых параметров.
(На самом деле, поскольку в MIPS нет выделенной обработки стека, мы можем использовать предварительное или последующее увеличение или предварительное или последующее уменьшение для добавления в стек до тех пор, пока мы используем точную обратную операцию для выталкивания из стека, а также при условии, что операционная система соответствует выбранной модели использования стека. Действительно, в некоторых встроенных системах и некоторых образовательных системах стек MIPS растет.)
-4(%rbp)
базовый указатель вообще не перемещается, и это+4(%rbp)
не может сработать.