Моя путаница с памятью, т. Е. Инстинкты Push и Pop - PullRequest
1 голос
/ 01 октября 2010

Я немного запутался с одной особенностью стека памяти.

Из того, что я знаю, стек создается для процесса / потока в памяти с более высоким адресом и продолжает работать с более низкими адресами.Теперь проблемная часть.Когда вы помещаете что-либо в стек, оно сначала уменьшает адрес, а затем сохраняет что-то в стеке.Не потеряна ли память, потому что инструкция Push сначала уменьшает адрес указателя стека?Я думаю, что было бы более логично сначала сохранить, а затем уменьшить Sp, где я не прав?

Спасибо за помощь

Ответы [ 3 ]

3 голосов
/ 02 октября 2010

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

2 голосов
/ 02 октября 2010

Более подробно, чем вы, вероятно, хотели бы знать.

Стеки могут быть как «нисходящими» (растущими), так и «восходящими» (растущими). Стеки также могут быть либо «полными» (SP указывает на «полную», то есть используемую запись в стеке), либо «пустыми» (SP указывает на «пустую», т.е. неиспользуемую запись в стеке.)

Большинство стеков "полностью нисходящие". Я думаю, что некоторые "пустые по возрастанию". Два других (FA, ED) не видят особого смысла, хотя бы потому, что неясно , на какой байт они должны указывать, если вы можете выдвигать / извлекать значения разных размеров.

РЕДАКТИРОВАТЬ: Приведенное выше наименование может быть немного специфичным для ARM, хотя бы в значительной степени потому, что большинство платформ не позволяют вам выбрать направление.

Каноническими мнемониками для соответствующих инструкций ARM на самом деле являются LDMIA (загрузка с несколькими кратными приращениями после) и STMDB (сохранение нескольких приращений перед) для стека «с полным нисходящим потоком», но ARM решила добавить псевдонимы LDMFD / STMFD, поэтому программистам нужно помните тип используемого стека. Увеличение / уменьшение до / после являются каноническими именами, потому что архитектура ARM (в основном) ортогональна; использование стека по соглашению (то есть EABI) вместо того, что предписано самой архитектурой. Исключениями являются r14 (LR), r15 (ПК) и набор регистров, которые затеняются между различными режимами супервизора.

Имена «приращение после» может быть более разумной, если вы используете ldm / stm для реализации чего-то вроде memcpy ().

(я игнорирую Thumb, в котором есть явные инструкции push / pop).

1 голос
/ 02 октября 2010

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

Было бы понятнее с иллюстрацией:

//initially
|    |    [CCCC|BBBB|AAAA]
          ^
         esp

//push
|    [    |CCCC|BBBB|AAAA] //decrement
     ^

|    [DDDD|CCCC|BBBB|AAAA] //store
     ^

//pop
|    [DDDD|CCCC|BBBB|AAAA] //load
     ^

|    |DDDD[CCCC|BBBB|AAAA] //increment
          ^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...