It creates the so-called stack stack and aligns it to addresses that can be divided by 16:
- Save stack pointer from program call on stack:
push ebp . - Create a new stack pointer for a program called:
mov ebp, esp - Align the stack to addresses that can be divided by 16 by setting the lowest bit to 0:
and esp, -16 - Create 16-byte space on the stack, for example, for local variables, etc .:
sub esp, 0x10
Why align?
The CPU always reads 16 bytes of data at once (depending on the type of processor). But it is read only from the address, which can be divided into 16: 0x0, 0x10, 0x20, .... And so on, because the least significant 4 bits are not used in the address bus. They are missing". When you read more bytes from an address, the CPU may need to read twice, because your address is sent to dword or sth, like this, this is true at the end of one address, which can be divided by 16 and your dword reaches the next address divisible by 16 By adding a stack to addresses that are divisible by 16, you reduce the risk of this when working with the stack.
You can see this in the example you posted. The ESP value is on the left and aligned to addresses shared by 16. It is easy to see because of the end of 0 :
0xbffffb70: 0xbffffb80: 0xbffffb90: 0xbffffba0: 0xbffffbb0: 0xbffffbc0: 0xbffffbd0: 0xbffffbe0:
source share