C language savior side story (explanation of the creation and destruction of function stack frames)

content

Creation and destruction of function stack frames

1. Register

Two of the key registers: ebp, esp. These two registers store the address, which is used to maintain the function stack frame

First of all, we must understand that each function call needs to open up a space on the stack area

into disassembly

1. We assign values ​​when creating variables. If the variables are created without assignment, the default is CCCCCCCC.

memory monitoring a

 memory monitoringb

function call

Enter inside the function (the order of operations in the first few steps is the same as the previous main function)

perform computing tasks

Addition is performed, but where are x, y?

The addition is complete, eax becomes 30

The formal parameters are not created inside the Add function, but come back to find the space data on the stack for calculation

We often say that a formal parameter is a zero-time copy of an actual parameter. This sentence is completely true. Changing the formal parameter does not affect the actual parameter.

function return

Do you have any doubts? When return z returns, isn't z destroyed? How can we bring the result back?

How is the return value brought back?

is that we first put it in the eax register, when we return to the function and put it in the local variable c

Back to the original question

 1. How are local variables created?

2. Why the uninitialized value of the local variable is a random value

3. How do functions pass parameters? What is the order in which the parameters are passed?

4. What is the relationship between formal parameters and actual parameters?

5. How is the function call done?

6. How is the result of the function call returned?


Note: The following environment is based on vs2013 for display

Creation and destruction of function stack frames

There should be many doubts in the process of learning, here are a few examples:

· How are local variables created?

Why is the uninitialized value of a local variable a random value?

How is the function passed parameters (what is the order of passing parameters)?

What is the relationship between formal parameters and actual parameters?

· How is the function call done?

· How does the function return after the end of the call?

Next, I will take you through the problem


1. Register

The storage system of the computer, in which the registers are integrated into the cpu

The registers we will encounter below are: eax, ebx, ecx, edx

Two of the key registers: ebp, esp. These two registers store the address, which is used to maintain the function stack frame


First of all, we must understand that each function call needs to open up a space on the stack area

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int a = 10;
	int b = 20;
	int c = 0;
	c = Add(a, b);

	return 0;
}

Start calling the main function, allocate space for the main function, and which function is called, ebp and esp will maintain the function stack frame of that function.

I want to call the Add function, ebp and esp run to maintain the Add function, the space between ebp and esp is the space opened up for the Add function call, which is called the function stack frame

Since the usage of the stack area is to use the high address first, then use the low address, and when placing data, put the data from the top to the bottom, so esp can be understood as the top pointer of the stack, and ebp is understood as the low pointer of the stack.

Have you ever wondered, the main function is called, but who is calling the main function?

Go down and execute the code, you can see __tmainCRTStartup, this function calls the main function internally, indicating that the main function is also called by others, and __tmainCRTStartup is called by tmainCRTStartup

The space for these two functions should also be allocated before the main function 

 

The outline is probably like this, how to call the next research


into disassembly

The main function is also called by others, and the __tmainCRTStartup that calls the main function has already created a space


Disassemble the first sentence (push: put an element on the top of the stack) (pop: delete an element from the top of the stack)

ebp stores the low address of the __tmainCRTStartup stack, push is called pushing the stack, putting elements in the stack

After push, the address of esp should also be changed

 monitor

watch esp and ebp, this is the initial address

When we start to push, the address is decreased by 4

RAM

It can be seen that ebp is indeed pushed in by push


Disassemble the second sentence

 The mov instruction is to assign the following value to the front, and esp to ebp

 


Disassemble the third sentence

 sub is a subtraction, subtract 0E4h from esp, and convert 0E4h to 228 in decimal

Monitoring (esp address changes, opening up a large space for the main function)

        


Disassemble the fourth, fifth, and sixth sentences


 Disassemble the seventh, eighth, ninth, and tenth sentences, lea =load effective address (load effective address)

 Load the following valid address into edi, this sentence is not very easy to observe, after we display the symbol name, it becomes ebp-0E4h

 

 mov puts 39h into ecx. Put the value of 0CCCCCCCCch into eax

Rep stos means that the data content of so many space dwords starting from the position of edi and going down 39h times should be changed to 0CCCCCCCCch.

A word is two bytes and a dword is four bytes

From edi to ebp stop, all the space contents are initialized to CCCCCCCC

memory monitoring

 


At this point, the main function stack frame has been opened, and the code execution is officially started below.

mov, put 0Ah (10 in decimal) in the position of ebp-8, we think that CCCCCCCC is four bytes, and the space opened up for a is the space from ebp to ebp-8

1. We assign values ​​when creating variables. If the variables are created without assignment, the default is CCCCCCCC.

The reason why the printing is hot is because it is a random value CCCCCCCC, which is not initialized. Different compilers may put different values ​​in it.

 

memory monitoring a

0a 00 00 00 is because this compiler is little endian

 memory monitoringb

14h is hexadecimal, converted to decimal is 20, leaving two integer positions empty

memory monitor c

It's a difference of two positions

 


function call

 Function calls need to pass parameters. Are the following two actions passing parameters?

mov, put ebp-14h (that is, b) in eax. push->eax, push the stack

mov, put ebp-8 (that is, a) in ecx. push->ecx, push the stack

The answer is indeed passing

 The call instruction is to call the function, now we remember the address of the call instruction

After executing the call instruction, the address of AA8 is 00 c2 14 50

The next address of the call instruction is pushed on the stack, why should I remember this address? Do not worry

 The Add function is called immediately after the call is called. After the Add function is called, it needs to return. I need to return to the next instruction of the call instruction (the call instruction is executed)


Enter inside the function (the order of operations in the first few steps is the same as the previous main function)

Prepare stack frame for Add function

First push ebp (at this time ebp is still maintaining the main function stack low), push the ebp value to the top 

Memory monitoring (ebp is pushed on the stack at the address of the next instruction under the call instruction)

Give the value of esp to ebp

esp, 0CCh is allocating function stack frame space for this call to Add

 


function load address

lea loads the address [ebp+FFFFFF34h] into edi, mov puts 33h into ecx, and then puts the value of 0XCCCCCCCCh into eax

rep -> all positions from edi down to ebp are initialized to 0XCCCCCCCCh

 


perform computing tasks

 put 0 in the position of ebp-8


Addition is performed, but where are x, y?

Put the value of ebp+8 into eax, ebp+8 finds ecx

ecx is pushed on the stack, we can call him a', and eax is b'

Put the value of ebp+8 into eax, and then add the value of ebp+0ch into eax

The addition is complete, eax becomes 30


How did the formal parameters come about? Are we actively creating parameters?

No, because we passed the parameters when we first called the function below

Passing parameters through the mov push mov push instruction

push pushes b first, then a. c=Add(a, b) The b passed first, the passed a, the parameters are passed from right to left

The formal parameters are not created inside the Add function, but come back to find the space data on the stack for calculation

We often say that a formal parameter is a zero-time copy of an actual parameter. This sentence is completely true. Changing the formal parameter does not affect the actual parameter.


function return

 

Do you have any doubts? When return z returns, isn't z destroyed? How can we bring the result back?

 return z means to put the value of ebp-8 into eax, which is a register. Registers are not destroyed when the program exits

ebp-8 position is z

Pop three sentences, pop, pop the top element of the stack and put it in edi, every time esp is popped, ++ goes down

mov assigns ebp to esp, esp does not point to the top of the stack, but points to the location of ebp (recycling the stack frame of the Add function)

Pop it, the stack low address of the ebp-main function was stored before (in order to prevent the stack low pointer from being found after the function is destroyed), ebp returns to the main function stack low address

 

 


At this point, after pop pops up, ebp returns to the main function stack low

ret instruction, esp returns to the address of 00C21450, which is the address of the next instruction of the call instruction, and continues to execute from the next instruction of the call instruction (not only to go out, but also to come back)

Add 8 to esp, skip parameters a, b, and destroy parameters a and b

 Put the value of eax into ebp-20h, the position of ebp-20h is the space of c, and the value of eax is sum: 30

How is the return value brought back?

is that we first put it in the eax register, when we return to the function and put it in the local variable c

 


The Add function is destroyed, and the main function is destroyed. This is the process of creating and destroying the function stack frame.

Back to the original question

 1. How are local variables created?

First, allocate the stack frame space for the function. After the stack frame space has initialized a part of the space, allocate a little space for my local variables in the stack frame.

2. Why the uninitialized value of the local variable is a random value

Because the random value is put in by the compiler, such as CCCCCCCC, if it is initialized, the random value will be overwritten

3. How do functions pass parameters? What is the order in which the parameters are passed?

When we haven't called the function, we have already pushed the stack from right to left. When we enter the formal parameter function, in the Add function, we find our formal parameter through the offset of the pointer.

4. What is the relationship between formal parameters and actual parameters?

The space created by the formal parameter when it is pushed on the stack is the same as the actual parameter value, the space is independent, and the formal parameter is a zero-time copy of the actual parameter. This sentence is completely correct. Changing the formal parameter does not affect the actual parameter.

5. How is the function call done?

The above summarizes clearly

6. How is the result of the function call returned?

Before the call, remember the address of the next instruction of the call instruction, and store the stack frame of the previous function of the ebp calling function. When the function returns after the function call, pop up the ebp to find the ebp of the original previous function. The pointer goes down to find the esp address

The return value is brought back through a register

The static variables created inside the function are opened globally. Today, we draw on the stack area.

Guess you like

Origin blog.csdn.net/weixin_63543274/article/details/123169306