2
votes

I'm new to assembly language and I was wondering about local variables, why do we (or the compilers) preserve a space for them on the stack usually by decrement the "ESP" register at the prologue of the procedure and as the procedure ends we assign the "ESP" it's old value again. like this code sample :

; 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

the last code snippet will do exactly if we removed the (sub esp,8) line and the (mov esp,ebp) line, to be as this

 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

so why we (or the compilers) do such behavior! , why don't we just use the stack memory to store our local variables as long as the "ESP" pointer will not affected by storing values on the stack with codes like:

mov DWORD PTR [ebp-8],20
2

2 Answers

1
votes

In general, you can only use the stack above the stack pointer. The stack pointer defines the end of the stack. Accessing under the stack pointer may or may not work. It especially won't work if you call another function, since the return address would be pushed and also the called function would start using the stack from the stack pointer, thereby overwriting your locals. Even in leaf functions, asynchronous things such as signal handlers may use the stack, and they also assume everything under the stack pointer is unused.

Furthermore, the OS may be growing your stack on-demand, and it also uses the stack pointer for that. If you access under the stack pointer, the memory might not even be mapped, and if the OS catches you doing that your program will crash.

Note that some calling conventions, such as the x86-64 abi, allow for a so-called red zone under the stack pointer. This area is guaranteed to be unmodified and can be used in leaf functions for the locals without adjusting the stack pointer.

0
votes

after mr. @Jester helpful answer I looked the "red zone" up and I found it very helpful for me, so I'm sharing it with you first this is it's definition from AMD64 ABI according to this article http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/

"The 128-byte area beyond the location pointed to by %rsp is considered to be reserved and shall not be modified by signal or interrupt handlers. Therefore, functions may use this area for temporary data that is not needed across function calls. In particular, leaf functions may use this area for their entire stack frame, rather than adjusting the stack pointer in the prologue and epilogue. This area is known as the red zone."

and here is a question that is very similar to mine:

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