When one function calls another function, you must first prepare the parameters of the called function. Then, the call command is executed to complete two tasks:
1. The next instruction of the called function is loaded into the stack. After the called function is returned, the instruction is taken to continue execution.
2. Modify the eip value of the instruction pointer register to point to the execution position of the called function.
To call a function, you must first create a new stack frame ):
Load the stack frame bottom address of the call function into the stack, and press the value of the bp Register into the call stack for future return.
Set the stack frame base address ebp = esp of the function to be called.
Function call and return process rules: These Rules are related to the operating system and compiler)
The parameter is pushed from right to left;
Ebp always points to the bottom of the stack frame;
The returned value is transmitted through the eax register;
The stack bottom of the called function stack frame stores the stack bottom of the call function stack frame;
A storage unit at the bottom of the stack of the called function stack frame stores the address of the next instruction returned by the function.
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/193I113D-0.png "title =" stack frame.png "alt =" 232614751.png"/>
Use the following code to explain the above rules.
Int bar (int c, int d)
{
Int e = c + d;
Return e;
}
Int foo (int a, int B)
{
Return bar (a, B );
}
Int main (void)
{
Foo (2, 3 );
Return 0;
}
Add the-g option during compilation. When using objdump disassembly, you can insert the C code and assembly code to display the relationship between the C code and the assembly code, here we only list what we care about: the instruction address is different each time it is compiled for reference only .)
080483b4 <bar>:
# Include <stdio. h>
Int bar (int c, int d)
{
80483b4: 55 push % ebp
80483b5: 89 e5 mov % esp, % ebp
80483b7: 83 ec 10 sub $0x10, % esp
Int e = c + d;
80483ba: 8b 45 0c mov 0xc (% ebp), % eax
80483bd: 8b 55 08 mov 0x8 (% ebp), % edx
80483c0: 8d 04 02 lea (% edx, % eax, 1), % eax
80483c3: 89 45 fc mov % eax,-0x4 (% ebp)
Return e;
80483c6: 8b 45 fc mov-0x4 (% ebp), % eax
}
80483c9: c9 leave
80483ca: c3 ret
080483cb <foo>:
Int foo (int a, int B)
{
80483cb: 55 push % ebp
80483cc: 89 e5 mov % esp, % ebp
80483ce: 83 ec 08 sub $0x8, % esp
Return bar (a, B );
80483d1: 8b 45 0c mov 0xc (% ebp), % eax
80483d4: 89 44 24 04 mov % eax, 0x4 (% esp)
80483d8: 8b 45 08 mov 0x8 (% ebp), % eax
8048db: 89 04 24 mov % eax, (% esp)
80483de: e8 d1 ff call 80483b4 <bar>
}
80483e3: c9 leave
80483e4: c3 ret
080483e5 <main>:
Int main (void)
{
80483e5: 55 push % ebp
80483e6: 89 e5 mov % esp, % ebp
80483e8: 83 ec 08 sub $0x8, % esp
Foo (2, 3 );
80483eb: c7 44 24 04 03 00 00 movl $0x3, 0x4 (% esp)
80483f2: 00
80483f3: c7 04 24 02 00 00 00 movl $0x2, (% esp)
80483fa: e8 cc ff call 80483cb <foo>
Return 0;
80483ff: b8 00 00 00 mov $0x0, % eax
}
(Gdb) stack frame of info registers bar function)
Esp 0xbffff718
Ebp 0xbffff728
Stack frame of the foo Function
Esp 0xbffff730
Ebp 0xbffff738
Stack frame of main Function
Esp 0xbffff740
Ebp 0xbffff748
650) this. width = 650; "src =" http://img1.51cto.com/attachment/201309/140921194.png "title =" functioncall.png "alt =" 140921194.png"/>
The above is the stack frame framework in the function call process. Now let's look at how to return it:
Bar function return process:
Mov-0x4 (% ebp), % eax; assign the value of e to eax.
Leave; it is the inverse operation of push % ebp and mov % esp, % ebp. The ebp value is assigned to esp. Now the esp value is 0xbffff728, and both ebp and esp point to the bottom of the bar stack. The ebp of the foo function is stored at the bottom of the stack. The ebp pops up. Now ebp points to the stack bottom of the foo function, and esp plus 4. esp points to the top of the stack of the foo function. The top stack of the foo function stores the next instruction address 80483e3 of the call command in the foo function. So far, the stack frame of the foo function has been returned.
Ret; this command is the inverse operation of the call Command. It restores the esp value to the eip and adds 4 to esp. After modifying the eip address of the program counter, we will jump to the address 80483e3, where the command is leave; ret; repeat the above process to return to the main function.
The main function calls foo, foo calls bar, bar returns foo, AND foo returns to the end of the entire main call process.
This article is from the "note" blog, please be sure to keep this source http://gcfred.blog.51cto.com/7948335/1302721