[Compilation and C-language relations] 1. Function calls

Source: Internet
Author: User

For the following programs:

intBarintCintd) {    intE = c +D; returne;}intFoointAintb) {    returnBar (A, b);}intMainvoid) {foo (2,3); return 0;}

With the-G option at compile time, the C Code and assembly code can be interspersed with objdump to display:

The disassembly results are long. The following sections are intercepted for analysis:

The entire program is executed by main calling Foo, Foo calling bar, using GDB to track the execution of the program until int e = c + D in the bar function, and when statement execution is ready to return, the function stack frame is printed in gdb.

Disassemble can disassemble the current function or the specified function, using disassemble alone is the disassembly of the current function, if the disassemble is followed by the function name or address to disassemble the specified function.

The s (step) command can be one-step debugging of one line of code, and the SI command can be a single-step debug with one instruction. BT lists the call stack

The info registers can display the current value of all registers. In GdB, the name of the register is preceded by a $, for example, p $ESP command to view the value of the ESP register (not shown), in the above example, the value of the ESP register is 0XBFF1C3F4, so x/20 $ The ESP command looks at the 20 32-bit numbers that begin in memory from the 0XBFF1C3F4 address. When executing the program, the operating system allocates a stack space for the process to store the function stack frame, the ESP register always points to the top of the stack, and on the x86 platform the stack is growing from a high address to a low address, each time a function is called to allocate a stack frame to store parameters and local variables, now we analyze how the data is stored, According to GDB's output, the following diagram shows:

On the way each of the small squares accounted for 4 bytes, such as B:3 the memory address of this square is 0xbf822d20~0xbf822d23. Let's start with the main function here:

To call the function Foo first to prepare the parameters, the second parameter is saved in the memory location pointed to by Esp+4, the first parameter is saved in the memory location that the ESP points to, the visible parameter is from right to left once the stack. Then execute the call command, which has two functions:

1. After the Foo function is called, the next instruction to return to call continues execution, so the address of the next instruction is 0x80483e9 to the stack, and the value of ESP minus 4,ESP is now 0xbf822d18.

2. Modify the program counter EIP to jump to the start of the Foo function.

Now look at the assembly code for the Foo function:

First, the value of the EBP register is compressed, and the value of the ESP is then reduced to 4,ESP, which is now 0XBF822D14, and the value is passed to the EBP register. In other words, the value of the original EBP is stored on the stack, and the new value is assigned to EBP. In the stack frame of each function, EBP points to the bottom of the stack, esp points to the top of the stack, and during function execution the ESP changes with the stack and the stack operation, and EBP is fixed, and the parameters and local variables of the function are accessed by the value of EBP plus an offset. For example, the parameters A and B of the Foo function are accessed through ebp+8 and ebp+12 respectively, so the following instruction pushes the arguments A and b again, prepares for the call bar function, and then pushes the return address stack, calling the bar function:

Now look at the bar function's instructions:

This time I saved the ebp of the Foo function, and then gave the EBP a new value, pointing to the bottom of the bar function stack frame, where the parameters C and D can be accessed by ebp+8 and ebp+12 respectively. The bar function also has a local variable e, which can be accessed through ebp-4. So the next few instructions mean to take the parameters C and D out of the register to do the addition, the result of the add command is saved in the EAX register, and then the EAX register back to the local variable e memory unit.

It is now possible to explain why the parameters and local variables on each stack frame can be viewed in gdb using the BT command and the frame command: If I am currently in the bar function, I can find the parameters and local variables of the bar function through EBP, or we can find the value of the EBP of the Foo function stored on the stack. The EBP of the Foo function can find its parameters and local variables, and it can also find the value of the EBP of the main function stored on the stack, so the stack frames of each function are strung by the value of EBP stored on the stack. Now look at the return command of the bar function:

The bar function has a return value of type int, which is passed through the EAX register, so the value of E is first read into the EAX register. Then execute the leave instruction, this command is the function at the beginning of the push%EBP and mov%esp,%ebp inverse operation:

1. Assign the value of EBP to ESP, now the value of ESP is 0XBF822D04.

2. Now the top of the stack that ESP points to holds the EBP of the Foo function stack frame, restores this value to EBP, while ESP increments by 4, and now the value of ESP is 0XBF822D08.

The last is the RET instruction, which is the inverse operation of the call command:

1. Now the top of the stack to which ESP is pointing is the return address, which restores the value to the EIP, while ESP increments by 4, and now the value of ESP is 0xbf822d0c.

2. Modified the program counter EIP, so jump to return address 0x80483c2 continue execution.

Address 0X80483C2 is the return instruction of the Foo function:

Repeating the same process, it returns to the main function. Note These rules in the function call and return process:

1. The parameter presses the stack to pass, and is to press the stack from right to left sequentially.
2. EBP always points to the bottom of the stack frame.
3. The return value is passed through the EAX register.
These rules are not imposed by the architecture, and the EBP registers do not have to be used, and the parameters and return values of the functions are not necessarily so, except that the operating system and compiler have chosen to implement the function calls in C code in this way, called calling convention, except calling Convention, the operating system also needs to specify the interface specification between many C code and binary directives, collectively known as the ABI (Application binary Interface).

[Compilation and C-language relations] 1. Function calls

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.