Является ли память стека смежной? - PullRequest
19 голосов
/ 23 февраля 2011

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

Ответы [ 3 ]

25 голосов
/ 23 февраля 2011

Стек для данного потока часто непрерывен в виртуальной памяти (в Linux и аналогичных системах, а также в пользовательском режиме в Windows).Ядро Windows (в Windows Vista и выше) и z / OS допускает непрерывные стеки в виртуальной памяти, а GCC 4.6 также допускает это .Компилятору вообще не нужно перемещать стек, даже для систем, которые имеют непрерывные виртуальные адреса для стека;они просто меняются, где размещаются новые части.Операционная система может преобразовывать физические страницы в виртуальные, чтобы стек не был непрерывным в физической памяти, даже если он находится в виртуальной памяти.

7 голосов
/ 23 февраля 2011

Нет требований к непрерывности стека в языке ОС или аппаратного обеспечения.

Я призываю всех разместить на сайте ссылку, в которой явно указано, что это требование.

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

Единственное требование стека состоит в том, что кадры связаны. Таким образом, позволяя стеку выдвигать / вставлять кадры при вводе / оставлении областей.

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

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

Как обычно реализуется стек.

Если бы это был вопрос. Тогда вы получите более подробный и точный ответ от сообщества.

4 голосов
/ 23 февраля 2011

У вас есть адресное пространство памяти, скажем, оно работает от 1 до 100. Вы выделяете свой стек от 1 и выше, а свою кучу - от 100 и ниже. Хорошо, пока?

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

Куча, с другой стороны, не так хорошо себя ведет, скажем, мы зарезервировали память от 70 до 100 для кучи. Мы можем выделить там блок из 4 байтов, и он может увеличиться с 70 до 74, затем мы выделим еще 4 байта, и теперь у нас есть память, выделенная от 70 до 78. Но эта память может быть освобождена в любой точке программы. Таким образом, вы можете освободить 4 байта, которые вы выделили в начале, создав таким образом дыру.

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

Я надеюсь дать разумный обзор по этому вопросу, но, возможно, есть лучшие авторы, чем я, и вам, вероятно, понравится читать намного больше. Так что ищите тексты в виртуальной памяти, это может быть хорошей отправной точкой для понимания того, что вы хотите. Есть несколько книг, которые опишут это более или менее подробно. Несколько из тех, что я знаю: структурированная компьютерная организация, от tanenbaum; Концепция операционной системы, автор Silberschatz. Я почти уверен, что Кнут обсуждает это и в своих книгах по алгоритмам. Если вы любите приключения, попробуйте прочитать о его реализации в x86 в руководствах Intel.

...