I am very new to assembly and I am currently reading a book called Reverse Engineering for Beginners and I got to the part that talks about memory allocation on the stack. I understand (I think) the concept of stack allocation but in the example there was something that I didn't understood and I'll be happy if anyone here can help.
The book give this function as an example:
#ifdef __GNUC__
#include <alloca.h> // GCC
#else
#include <malloc.h> // MSVC
#endif
#include <stdio.h>
void f()
{
char *buf=(char*)alloca (600);
#ifdef __GNUC__
snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3); // GCC
#else
_snprintf (buf, 600, "hi! %d, %d, %d\n", 1, 2, 3); // MSVC
#endif
puts (buf);
};
I understand what the C function does. It allocates 600 bytes of memory on the stack and than writes to that space the string "hi!" using the _snprintf
function. Then the function prints it.
All good for now. After that the book gives the assembly implementation that the MSVC compiler produced and the code looks like this:
mov eax, 600 ; 00000258H
call __alloca_probe_16
mov esi, esp
push 3
push 2
push 1
push OFFSET $SG2672
push 600 ; 00000258H
push esi
call __snprintf
push esi
call _puts
add esp, 28
Here I understand that the EAX
register will contain the argument for the __alloca_probe_16
function.
but now something doesn't make sence to me. From what I understand the function __alloca_probe_16
basically just subtracts the number of bytes that is in the value of EAX
from ESP
.
So for example if ESP
points to 1000 now it points to 400. Then we store the 400 into ESI
and start pushing arguments of _snprintf
to the stack and ESI
is pointing to the location of where the function needs to start writing data to.
So my problem is this, if both the ESP
and ESI
registers point to 400 and I allocated memory from 1000-400 (600 bytes), and I start pushing things onto the stack, won't they go in to the position starting from 400 and decreasing? I mean, why did it subtract 600 byte if it is not using them?
In my eyes this is how the stack looks like after the push esi
line.
| 400 |
| 600 |
| adrr of string |
| 1 |
| 2 |
| 3 | 400 , ESP , ESI
| | ...
|_______________________| 1000
I know that I am probably wrong and didn't understand something right because I don't think the book is wrong, I'll be happy if someone can help me to understand what is happening in this assembly code.