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 +0x8
andsub esp,byte +0xc
at offsets0x03
and0x06
?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 singlesub
because you compiled without optimisations. Try to compile withgcc -O4 ...
– Jabberwocky