1: instruction
call instructiontempEIP <-- EIP + DEST; (* DEST is rel32 *)IF tempEIP is not within code segment limit THEN #GP(0); FI;IF stack not large enough for a 4-byte return addressTHEN #SS(0); FI;Push(EIP);EIP <-- tempEIP; <==> pushl %eipret instructioneip <-- pop <==> popl %eipleave instructionesp <-- ebp <==> movl %ebp, %espebp <-- pop <==> popl %ebpenter instructionpushl %ebpmovl %esp, %ebp......
2: Call Process
- Prepare to call ==> prepare the input parameters, put them into 8 (% EBP), 12 (% EBP), 16 (% EBP), 20 (% EBP )...
- Call function ==> pushl % EIP
- Create stack ==> enter
- ==> Pushl % EBP
- ==> Movl % ESP, % EBP
- Do something
- Destory stack ==> leave
- ==> Movl % EBP, % ESP
- ==> Popl % EBP
- Ret => popl % EIP
3: Stack
main -- ebp -4 -8 ==> ret = 28(%esp) -c ==> second = 24(%esp) -10 ==> first = 20(%esp) -14 -18 -1c ==> second - in parameter - 4(%esp) ==> 12(%ebp)esp --> -20 ==> first - in paramter - (%esp) ==> 8(%ebp)call sum:esp --> EIP ==> *(eip) = the instruction next to call sumsum -- ebp ==> ebp = esp; *(ebp) = prev_ebp -4 ==> ret = -4(%ebp) -8 -c -10
4: C source code
#include <stdio.h>int sum(int a, int b){ int ret; ret = a + b; return ret;}int main(int argc, char* argv[]){ int first = 5; int second = 6; int ret ; ret = sum(first, second); printf("ret = %d\n", ret); return 0;}
5: assembly code gcc-S-fno-asynchronous-Unwind-tables stack. c
.file"stack.c".text.globlsum.typesum, @functionsum:# 3. create the stack frame pushl%ebpmovl%esp, %ebp# 4. alloc the stack space ==> ret = -4(%ebp)subl$16, %esp# 5. get the parameters from the higher stack movl12(%ebp), %eaxmovl8(%ebp), %edx# 6. calculation addl%edx, %eax# 7. put the result into retmovl%eax, -4(%ebp)# 8. call convention, $eax is the return value movl-4(%ebp), %eax# 9. destory stack frame leave# 10. popl %eipret.sizesum, .-sum.section.rodata.LC0:.string"ret = %d\n".text.globlmain.typemain, @functionmain: # create the stack frame pushl%ebpmovl%esp, %ebp # 16 bytes alignmentandl$-16, %esp # alloc stack spacesubl$32, %esp # initialize the input parameters movl$5, 20(%esp)movl$6, 24(%esp)# 1. prepare the input parameters movl24(%esp), %eaxmovl%eax, 4(%esp)movl20(%esp), %eaxmovl%eax, (%esp)# 2. call the function sum ==> push %eipcallsum# 11. get the return value movl%eax, 28(%esp)# prepare the input parameters for printf movl28(%esp), %eaxmovl%eax, 4(%esp)movl$.LC0, (%esp) # call the function printfcallprintf# set the return value movl$0, %eax# destroy the stack frame leave# popl %eipret.sizemain, .-main.ident"GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3".section.note.GNU-stack,"",@progbits
6: Binary Code objdump-d
0804841c <sum>: 804841c:55 push %ebp 804841d:89 e5 mov %esp,%ebp 804841f:83 ec 10 sub $0x10,%esp 8048422:8b 45 0c mov 0xc(%ebp),%eax 8048425:8b 55 08 mov 0x8(%ebp),%edx 8048428:01 d0 add %edx,%eax 804842a:89 45 fc mov %eax,-0x4(%ebp) 804842d:8b 45 fc mov -0x4(%ebp),%eax 8048430:c9 leave 8048431:c3 ret 08048432 <main>: 8048432:55 push %ebp 8048433:89 e5 mov %esp,%ebp 8048435:83 e4 f0 and $0xfffffff0,%esp 8048438:83 ec 20 sub $0x20,%esp 804843b:c7 44 24 14 05 00 00 movl $0x5,0x14(%esp) 8048442:00 8048443:c7 44 24 18 06 00 00 movl $0x6,0x18(%esp) 804844a:00 804844b:8b 44 24 18 mov 0x18(%esp),%eax 804844f:89 44 24 04 mov %eax,0x4(%esp) 8048453:8b 44 24 14 mov 0x14(%esp),%eax 8048457:89 04 24 mov %eax,(%esp) 804845a:e8 bd ff ff ff call 804841c <sum> 804845f:89 44 24 1c mov %eax,0x1c(%esp) 8048463:8b 44 24 1c mov 0x1c(%esp),%eax 8048467:89 44 24 04 mov %eax,0x4(%esp) 804846b:c7 04 24 10 85 04 08 movl $0x8048510,(%esp) 8048472:e8 79 fe ff ff call 80482f0 <printf@plt> 8048477:b8 00 00 00 00 mov $0x0,%eax 804847c:c9 leave 804847d:c3 ret 804847e:66 90 xchg %ax,%ax