In-depth analysis of GCC function call stack changes

Source: Internet
Author: User

From: http://stackoverflow.com/questions/2515598/push-ebp-movlesp-ebp

 

When we analyze the at&t Assembly statements generated by GCC through disassembly, we often find that there are always the following two Assembly statements at the beginning of function calling:

Push % EBP

Movl % ESP, % EBP

At the end of the function call, you can see:

Leave

RET

 

Here I searched for some instructions on the Internet. tenfy simply translated the corresponding English instructions and added his own understanding and instructions. For a better description of the function call's inbound stack process, refer to the following brief illustration:

 

The following translation description:

Can anybody explain me what effect these two instructions cause in the assembly code generated by GCC for x86 machines:

Can someone tell me what the two GCC compilers do for the Assembly commands generated by x86 machines?

Push % EBP
Movl % ESP, % EBP

 

Answer 1:

% EBP is the "base pointer" for your stack frame. it's the pointer used by the C runtime to access local variables and parameters on the stack. here's some typical function prologue code generated by GCC (G ++ to be precise) first the C ++ source.

Register % EBP (tenfy note: In at&t assembly, the reference register must be prefixed with %. In Embedded Assembly with C/C ++, the prefix with % is required) the base address of the current "stack frame" during the function call process. This base address is a pointer to the local variables and parameters used in the C Runtime Library to access the stack. Here are some typical codes that are most executed in function calls generated by GCC (G ++). The C ++ source code is as follows:

 

// Junk. c ++
Int addtwo (int)
{
Int x = 2;

Return A + X;
}

 

 

This generates the following extends er.

Generate the following assembly language:

 

. File "junk. c ++"
. Text
. Globl _ z6addtwoi
. Type _ z6addtwoi, @ Function
_ Z6addtwoi:
. Lfb2:
Pushl % EBP # tenfy: the stack frame pointer address that calls the function is first added to the stack. Before that, the corresponding real parameters and return addresses are already included in the stack.
. Lcfi0:
Movl % ESP, % EBP # tenfy: Assign the top pointer of the current stack to % EBP so that the new stack frame pointer of the current call is consistent with % ESP, at this time, % EBP and % ESP point to the same point.
. Lcfi1:
Subl $16, % ESP # tenfy: the pointer at the top of the current stack minus 16, so that the current % ESP moves 16 bytes to the memory address, reserved space for local variable Storage
. Lcfi2:
Movl $2,-4 (% EBP) # tenfy: Assign the number of immediately 2 to the memory unit of % ebp-4, as you can see, that is, four bytes are moved from the base address % EBP to the lower part of the memory, and INT x = 2 is written.
Movl-4 (% EBP), % edX # Write X to the Register % edX
Movl 8 (% EBP), % eax # tenfy: 8 (% EBP) means % EBP moves 8 bytes to the high-address memory, that is, the stack address of real parameter 1, write the value of real parameter A into Register % eax
Addl % edX, % eax # tenfy: add the registers % EDX and % eax and store them to % eax. Note: % eax is also the register of GCC as the return value of the storage function.
Leave
RET
. Lfe2:
. Size _ z6addtwoi,.-_ z6addtwoi
. Ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
. Section. Note. GNU-stack, "", @ progbits

 

Now to explain that prologue code (all the stuff before. lcfi2 :), first:

Start to describe the code at the beginning (all the code before. lcfi2). First

1, pushl % EBP stores the stack frame of the calling function on the stack. (call the function stack frame into the stack)
2, movl % ESP, % EBP takes the current stack pointer and uses it as the frame for the called function. (the top pointer of the current stack serves as the stack frame of the new function call)
3, subl $16, % ESP leaves room for local variables. (reserved space for local variables)

Now your function is ready for business. any references with a negative offset from the % EBP % register are your local variables (X in this example ). any references with a positive offset from the % EBP % register are your parameters passed in.

Now all your function calls are ready. All references to the negative offset of the relative register % EBP are local variables (for example, the X variable in this example ), all references to the positive offset of the relative register % EBP are real parameters.

 

The final point of interest is the leave instruction which is an x86 worker er instruction which does the work of restoring the calling function's stack frame. this is usually optimized away in to the Faster Move % EBP % ESP and pop % EBP % sequence in
C Code. For example strative purposes, however, I didn't compile with any optimizations on at all.

The last key to interest is the command leave, which is an x86 Assembly command used to restore the stack frames that call functions. This command is often used to optimize the sequence of commands in C code: Move % EBP % ESP and pop % EBP. However, to be more descriptive, I did not turn on any optimization switch at all during compilation.

 

Answer 2:

It's typical code that you see at the beginning of a function.

This is a typical code that you often see at the beginning of the function call.

 

It saves the contents of the EBP register on the stack, and then stores the content of the current stack pointer in EBP.

It first stores the content of register % EBP to the stack (inbound stack operation), and then assigns the content of the current stack pointer to register % EBP

 

The stack is used during a function call to store local arguments. But in the function, the stack pointer may change because values are stored on the stack.

The stack is often used to store local parameters in function calls, but the value of the stack pointer is often changed because of the value stored in the stack in the function.

 

If you save the original value of the stack, you can refer to the stored arguments via the EBP register, while you can still use (add values to) the stack.

If you put the original value into the stack, you will be able to reference the corresponding storage parameters through the Register % EBP, and even you can continue to use (added to the stack) the stack.

 

At the end of the function you will probably see the command

At the end of the function, you will see the following command:

Pop % EBP; restore original value
RET; Return

 

Answer 3:

Push % EBP

This will push the 32 bit (extended) base pointer register on the stack, I. e. the stack pointer (% ESP) is subtracted by four, then the value of % EBP is copied to the location that the stack pointer points.

This will cause the 32-bit base address register to be pushed into the stack, that is, the current stack pointer (stored in register % ESP) minus 4, copy the content of the register % EBP to the corresponding location (that is, the stack location of % ESP)

 

Movl % ESP, % EBP

This copies the stack pointer register to the base pointer register.

This copies the register % esp of the current stack pointer to the base register % EBP.

 

The purpose of copying the stack pointer to the base pointer is to create a stack frame, I. e. an area on the stack where a subroutine can store local data. the code in the subroutine wocould use the base pointer to reference the data.

The purpose of this copy is to create a "stack frame", that is, to open up an area in the stack, which stores local data for subsequent calling sub-processes, the sub-course code can use the "base address" here to access relevant data.

 

It's part of what is known as the function Prolog.

It saves the current base pointer that is going to be retrieved when the function ends and sets the new EBP to the beginning of the New Frame

 

 

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.