I wrote below code.
int main (int argc, char *argv[])
{
char *uargv[3];
uargv[0] = "echo";
uargv[1] = "hello!";
uargv[2] = 0;
exec("echo", uargv);
exit();
}
And compiled with gcc 5.4.
Below is assembly code of above program.
0x00: lea 0x4(%esp),%ecx
0x04: and $0xfffffff0,%esp
0x07: pushl -0x4(%ecx)
0x0a: push %ebp
0x0b: mov %esp,%ebp
0x0d: push %ecx
0x0e: sub $0x14,%esp
0x11: movl $0x7c3,-0x14(%ebp)
0x18: movl $0x7c8,-0x10(%ebp)
0x1f: movl $0x0,-0xc(%ebp)
0x26: sub $0x8,%esp
0x29: lea -0x14(%ebp),%eax
0x2c: push %eax
0x2d: push $0x7c3
0x32: call 2ce <exec>
0x37: add $0x10,%esp
0x3a: call 296 <exit>
I can't understand three part of above assembly code.
First, in the code that is in 0x00, 0x04, 0x07, 0x0a, 0x0b, 0x0d works as follows.
0x00: save ebp+4 to ecx, and it is address of argc.
0x04: align esp with 16 byte
0x07: push ecx-4 to stack, and it is return address.
0x0a ~ 0x0b: setup ebp
0x0d: push ecx to stack, and it is address of argc.
I wonder why it push return address again and why it push address of argc.
It was my first question.
Second, it allocate stack in 0x0e instruction for local variable, uargv.
However, the size of uargv is only 12 byte.
But it allocate 20 byte.
If it is because of 16 byte alignment, why local variables are saved in esp+4, not esp (ebp+0x14 is same with esp+4).
Third, why 0x26 instruction allocate more 8 byte for stack?
More space in stack is no needed, because arguments of exec are saved in stack by push instruction.
Thank you.