Стек
Стек – это
последовательный список, у которого имеется только один конец, т.е. работа с
ним ведется по принципу FIFO (First In, First Out – Первый пришел, последний ушел). Стек можно сравнить со стопкой пронумерованных листков, если
мы будем их слаживать на полку по номерам 1, 2 и 3, то взять от туда удастся
только в обратном порядке 3, 2 и 1. В основном стек различается на системный и
программный. Системный стек, как вы надеюсь, поняли, это участок памяти,
который выделят операционная система, а программный создается программистом,
притом, что для работы с таким видом стека можно использовать свои макросы (см.
прил.1.), а можно подменять стеки и работать с ним как с системным (см. прил.2.).
Стек располагается в сегменте памяти, описываемом регистром SS, а текущее смещение вершины стека
записано в регистре ESP. При вызове
подпрограммы параметры в большинстве случаев помещают в стек, а в EBP записывают текущее значение ESP. Тогда, если подпрограмма
использует стек для хранения локальных переменных, ESP изменится, но EBP
можно будет использовать для того, чтобы считывать значения параметров напрямую
из стека (их смещения будут записываться как EBP + номер параметра*4). При записи смещение в ESP уменьшается, то есть стек
растет вниз от максимально возможного адреса (рис. 1).Такой принцип
унаследован в Windows от старых ОС, в которых зачастую использовали бессегментнуюмодель памяти, т.к. все сегменты, включая сегмент стека и сегмент
кода, занимают одну и ту же область — всю память. Тогда программа
исполняется в нижней области памяти, в области малых адресов, и EIP растет, а стек располагается в
верхней области памяти, и ESP
уменьшается. Так же Windows использует проверку стека, т.е. если вы выделите память в
каком либо размере который не кратен 8, то вызов любой API функции с
передачей параметров через ваш стек завершиться ошибкой.
|