What is `and esp, 0xfffffff0`?

When I parse main() in gdb, it reconfigures this result:

  0x0804854c <+0>: push ebp 0x0804854d <+1>: mov ebp,esp 0x0804854f <+3>: and esp,0xfffffff0 0x08048552 <+6>: sub esp,0x10 

and in the code that I am considering esp , register as follows:

 x/32xw $esp 

and it does the following:

 0xbffffb70: 0xb7ea1515 0xb7ff0590 0x080485eb 0xb7fd2ff4 0xbffffb80: 0x080485e0 0x00000000 0xbffffc08 0xb7e88e46 0xbffffb90: 0x00000002 0xbffffc34 0xbffffc40 0xb7fe0860 0xbffffba0: 0xb7ff6821 0xffffffff 0xb7ffeff4 0x080482bc 0xbffffbb0: 0x00000001 0xbffffbf0 0xb7fefc16 0xb7fffac0 0xbffffbc0: 0xb7fe0b58 0xb7fd2ff4 0x00000000 0x00000000 0xbffffbd0: 0xbffffc08 0xd51689cb 0xfbfdbfdb 0x00000000 0xbffffbe0: 0x00000000 0x00000000 0x00000002 0x08048400 

I want to know what is the relationship between and esp,0xfffffff0 and these results.

+6
source share
3 answers

and esp,0xfffffff0 provides 16 byte stack matching, which is a general ABI requirement. It does this by masking (zeroing) the least significant 4 bits of the stack pointer, which is equivalent to rounding to the nearest multiple of 16.

+10
source

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: 
+6
source

Apparently, and esp,0xfffffff0 removes the bottom nib of esp , masking it.

0
source

Source: https://habr.com/ru/post/982367/


All Articles