# Basic hello world stack manipulation troubles

I'm a beginner in reverse engineering, and as a beginner I started to read "Reverse Engineering for beginers".
Here is the hello world program from the book (taken from chapter 3, page 12) :

Now let’s try to compile the same C/C++ code in the GCC 4.4.1 compiler in Linux: gcc 1.c -o 1 Next, with the assistance of the IDA disassembler, let’s see how the main() function was created. IDA, like MSVC, uses Intel-syntax5.

``````main proc near

var_10 = dword ptr -10h

push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov eax, offset aHelloWorld ; "hello, world\n"
mov [esp+10h+var_10], eax
call _printf
mov eax, 0
leave
retn
main endp
``````

There are two lines I don't understand at all :

• `and esp, 0FFFFFFF0h`
• `sub esp, 10h`

From what I understood from the book, we add `0FFFFFFF0h` (equals -16) value to ESP in order to align the stack to a 16byte boundary for optimisation.
My question is : why do we add -16 and then substract 16 to the stack? It seems pointless to me, can't we substract directly 32? Second, if I'm understanding well:

• the program starts with EBP = ESP, because nothing is on the stack.
• Then EBP is pushed to the stack. Assuming the program is 64bit, ESP is now EBP - 8 (because of the 64bits). So now we have ESP != EBP.
• Then we copy the content of ESP into EBP. So we have EBP = ESP, and EBP = fristEBP (EBP when the program started) - 8.

Why do we need to modify the value of EBP? PUSH instruction is supposed to change the value of ESP, not EBP, so why would there be any problem not modifying EBP value at the function prolog?

So now we have EBP = ESP, and both are fristEBP (EBP when the program started) - 8. So now we are adding -16 to the stack, so ESP becomes ESP - 16 (ESP - 24 if we consider that we've been adding -8 to the stack).
What is -24 have to do with a 16byte boundary? Why do we substract 16 again from the stack with `sub esp, 10h`?

Notes : I'm sorry for the english, and sorry if I'm asking dumb questions, the book isn't clear enought and I failed to find explainations on the net.

• and not add aligns the stack to 16 byte boundary ie 123456a1 & fffffff0 will result in 123456a0 May 31, 2018 at 10:14
• Isn't there a risk of loosing data?
– Nark
May 31, 2018 at 18:49

It's not `add` in the first opcode. It's `and`. So it will clear the lower nibble for the last byte in the address. This is how the alignment is done and not by adding anything. Only later you `sub` 16 to have room for the local variables.

Why do we need to modify the value of EBP?

We use `EBP` to store the initial `ESP` value. `EBP` is pointing to the current stack frame. This is the place for local variables created withing the function. Before we modify `EBP` it is stored on the stack so that we can restore it before we leave the function.

• Okay I get it, but why add 0FFFFFFF0h and not 0FFFFFFF0F if we want to clear the lower nibble?
– Nark
May 31, 2018 at 9:48
• lower nibble are the bits `3-0` so why we would want to put 0 on bits `7-4` to do that? May 31, 2018 at 9:53