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 +0x8andsub esp,byte +0xcat offsets0x03and0x06?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
sub esp,byte + ...are probably not contracted into a singlesubbecause you compiled without optimisations. Try to compile withgcc -O4 ...- Jabberwocky