Зачем сохранять пространство стека для локальных переменных?

Я новичок в языке ассемблера, и мне было интересно узнать о локальных переменных: почему мы (или компиляторы) сохраняем для них место в стеке, обычно уменьшая регистр "ESP" в прологе процедуры и по окончании процедуры мы присваиваем "ESP" его старое значение снова. как этот пример кода:

; a procedure that create the stack frame then assign 10, 20 values for two local variables then return to caller

two_localv_proc PROC
push ebp
mov ebp,esp
sub esp,8
mov DWORD PTR [ebp-4],10
mov DWORD PTR [ebp-8],20
mov esp,ebp
pop ebp
ret
two_localv_proc ENDP

последний фрагмент кода будет работать точно, если мы удалили строку (sub esp,8) и строку (mov esp,ebp), чтобы это было так

 two_localv_proc PROC
push ebp
mov ebp,esp
mov DWORD PTR [ebp-4],10
mov DWORD PTR [ebp-8],20
pop ebp
ret
two_localv_proc ENDP

так почему мы (или компиляторы) делаем такое поведение! почему бы нам просто не использовать стековую память для хранения наших локальных переменных, если на указатель "ESP" не повлияет сохранение значений в стеке с помощью таких кодов:

mov DWORD PTR [ebp-8],20

2 ответа

Решение

В общем, вы можете использовать только стек над указателем стека. Указатель стека определяет конец стека. Доступ по указателю стека может или не может работать. Это особенно не будет работать, если вы вызовете другую функцию, так как будет возвращен адрес возврата, а также вызываемая функция начнет использовать стек из указателя стека, тем самым перезаписывая ваши локальные данные. Даже в конечных функциях асинхронные объекты, такие как обработчики сигналов, могут использовать стек, и они также предполагают, что все, что находится под указателем стека, не используется.

Кроме того, ОС может увеличивать ваш стек по требованию, и для этого также используется указатель стека. Если вы обращаетесь к указателю стека, память может даже не отображаться, и если операционная система перехватит вас, ваша программа вылетит.

Обратите внимание, что некоторые соглашения о вызовах, такие как abi x86-64, допускают так называемую красную зону под указателем стека. Эта область гарантированно не изменена и может использоваться в листовых функциях для местных жителей без настройки указателя стека.

После г-на. Полезный ответ @Jester Я посмотрел на "красную зону" и нашел ее очень полезной для меня, поэтому сначала делюсь ею с вами, это определение AMD64 ABI в соответствии с этой статьей http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/

"128-байтовая область за пределами местоположения, на которое указывает% rsp, считается зарезервированной и не должна изменяться обработчиками сигналов или прерываний. Поэтому функции могут использовать эту область для временных данных, которые не нужны при вызовах функций. В частности, Листовые функции могут использовать эту область для всего кадра стека, вместо того, чтобы регулировать указатель стека в прологе и эпилоге. Эта область называется красной зоной ".

и вот вопрос, который очень похож на мой:

https://softwareengineering.stackexchange.com/questions/230089/what-is-the-purpose-of-red-zone/230095

Другие вопросы по тегам