I'm following section 5.1.3 at OS development by Nick Blundell. I'm investigating how the following C code is compiled into machine code:
void caller_fun(){
        callee_fun(0xdede);
}
int callee_fun(int arg){
        return arg;
}
My final dis-assembled machine code by ndisasm is this:
00000000  55                push ebp
00000001  89E5              mov ebp,esp
00000003  83EC08            sub esp,byte +0x8
00000006  83EC0C            sub esp,byte +0xc
00000009  68DEDE0000        push dword 0xdede
0000000E  E806000000        call dword 0x19
00000013  83C410            add esp,byte +0x10
00000016  90                nop
00000017  C9                leave
00000018  C3                ret
00000019  55                push ebp
0000001A  89E5              mov ebp,esp
0000001C  8B4508            mov eax,[ebp+0x8]
0000001F  5D                pop ebp
00000020  C3                ret
Studying on how the stack pointer and base pointer work, I made the following diagram which shows stack situation when the opcode at offset 0x1C is being run by the processor:
                 Stack situation when processor is
             running `mov eax,[ebp+0x8]` at offset 0x1C
    +---------------------------------+
    |           4 bytes for           |
    |    `push ebp` at offset 0x00    |
    +---------------------------------+
    |        20 (8+12) bytes for      |
    |        `sub esp,byte +0x8`      |
    |    and `sub esp,byte +0xc`      |
    |    at offsets 0x03 and 0x06     |
    +---------------------------------+
    | 4 bytes for `push dword 0xdede` |
    |         at offset 0x09          |
    +---------------------------------+
    | 4 bytes for instruction pointer |
    |      by `call dword 0x19`       |
    |        at offset 0x0E           |
    +---------------------------------+
    |     4 bytes for `push ebp`      |
    |        at offset 0x19           |
    +---------------------------------+ --> ebp & esp are both here by 
                                               `mov ebp,esp`
                                              at offset 0x1A
Now, I have questions which I couldn't figure out by researching and studying:
- Is my diagram of stack situation correct? 
- Why are 20 bytes pushed into the stack by - sub esp,byte +0x8and- sub esp,byte +0xcat offsets- 0x03and- 0x06?
- Even if 20 bytes of stack memory is needed, why is it not assigned by a single instruction like - sub esp,byte +0x14, i.e.- 0x14=0x8+0xc
I'm compiling the C code with this make-file:
all: call_fun.o call_fun.bin call_fun.dis
call_fun.o: call_fun.c
    gcc -ffreestanding -c call_fun.c -o call_fun.o
call_fun.bin: call_fun.o
    ld -o call_fun.bin -Ttext 0x0 --oformat binary call_fun.o
call_fun.dis: call_fun.bin
    ndisasm -b 32 call_fun.bin > call_fun.dis
 
    