Do you want to know why you use vs to hit "hot" when crossing the border?
Do you want to know how temporary variables are destroyed after a function call?
Welcome to follow me ♥， Subscribe to column 0 basic C language nanny teaching,
You can continue to read my article 😀🐕~~~~
Here are full of dry goods, starting from zero ~, step by step 😀， Until you have basically learned all the knowledge in C 🐂.
This article is the Ninth Section - a simple understanding of the creation and destruction of function stack frames from the perspective of bottom assembly 👉
Now, we have a better understanding of how functions work, including how to pass parameters, function calls and so on. However, it is only understood to be useful,
What is the underlying principle and how to call it? We will discuss it in detail in this section.
First, we need to know that the creation and destruction of function stack frames are completed in the stack area. Every function call has the creation and destruction of stack frames.
When the system uses addresses in the stack area, it uses them from high addresses to low addresses. That is, use the high address first, and then the low address.
Let's simply draw a picture
Then we need to understand the two registers: ebp and esp
They are used when the function creates stack frames. Used to maintain function stack frames.
EBP (stack bottom pointer) stores the address at the bottom of the stack
esp (stack top pointer) stores the address of the top of the stack
Let's simply write a program:
For ease of understanding, I break this code down enough.
ok, now let's start to see how the bottom layer is implemented.
We press and hold F10 to get the code running, then go to disassembly, turn on memory and monitoring.
Anyway, I saw such a mess.
The lines on the left are actually assembly code. It should be noted that we will not analyze lines 11 and 12 for the time being, because they are made by vs2019 and optimized. If you use vs2013 or even older versions, it will basically not appear. (the process of creating and destroying function stack frames is similar in different compilers and environments)
Note that you first need to create a stack frame for the main function, so the previous lines are doing things for the main function.
Let's analyze it bit by bit:
First three lines:
002617C0 push ebp It means to press the stack ebp Stack. 002617C1 mov ebp,esp It means to ebp Give me the value of your address esp.
At this time, the diagram of our stack area can be understood as follows:
(stack area diagram at this time)
002617C3 sub esp,0E4h Indicates that it will esp Subtract 0 from the value of E4h，0E4h Is a hexadecimal number that represents 0 x00 00 00 e4
At this time, the diagram becomes like this:
We can let the code go and see if the value of ebp and esp is as we said.
Let's move on:
002617C9 push ebx 002617CA push esi 002617CB push edi They all mean the same. push... Is to...Push into stack He will separate ebx esi edi Push into the stack (they are all register types)
At this time, we get the stack area diagram as follows:
Lines 7 to 10 are for one thing. Let's look at:
002617CC lea edi,[ebp-24h]
002617CF mov ecx,9
002617D4 mov eax,0CCCCCCCCh
002617D9 rep stos dword ptr es:[edi]
002617CC lea edi,[ebp-24h] //It means to read the address from ebp-24h to edi and assign ebp-24h to edi
mov ecx,9 //The meaning is to change the value of ecx to 9
mov eax,0CCCCCCCCh //The meaning is to change the value of eax to 0cch
002617D9 rep stos dword ptr es:[edi] //It means ecx (0Ch) data from edi (Or dword So many times, so many data) are all changed to eax 0 of CCCCCCCCh Then let edi Stored ebp Value of
In addition, note that it has been done 9 times, but each time it is a dword, double word, 4 bytes. A cc is a byte. So what you should see is 36 cc. So it happens to be the corresponding number of times, no more or less.
Then, the stack area diagram we just drew can be expressed as follows:
This explains why we sometimes type "hot" when we cross the border, because 0xccc corresponds to "hot"
Look at the next three lines
int a = 10; 002617E5 mov dword ptr [ebp-8],0Ah int b = 20; 002617EC mov dword ptr [ebp-14h],14h int c = 0; 002617F3 mov dword ptr [ebp-20h],0
We also copied our source code.
Or line by line:
002617E5 mov dword ptr [ebp-8],0Ah //It means that the position dword of ebp - 8 (commonly referred to as assignment) is 0Ah (0Ah Is a hexadecimal number, which is 0 x00 00 00 0A,It happened to be us a Value of 10)
The diagram of our stack area at this time can be drawn as follows:
The following two lines are the same:
002617EC mov dword ptr [ebp-14h],14h //Assign the position of ebp - 14h to 14h
002617F3 mov dword ptr [ebp-20h],0 //Assign the position of ebp-20h to 0
Then add two more variable values to the diagram
OK, let's take a look at how to call the Add function?
Let's look at it in two lines:
002617FA mov eax,dword ptr [ebp-14h] 002617FD push eax //Assign the value of ebp -14h position to eax Then let eax Stack pressing
Notice that ebp - 14h happens to be the location of the parameter b we want to pass.
The following two lines are the same:
002617FE mov ecx,dword ptr [ebp-8] 00261801 push ecx take ebp -8 The value of the position is assigned to ecx in Then let ecx Stack pressing
Then, the current stack area diagram can be understood as follows:
Continue down, and then we need to press and hold F11
Means to call the function, and remember the address of a line of instructions under call (that is, 00261807)
F11 press in,
call 002613BB We came to the instruction 002613 BB Such a line of assembly code jmp 002625D0 Jump to 002625 D0
Continue to press and hold F11
At this point, the user-defined function is formally entered.
From the just jump 002625D0, we jump to such a line of assembly instructions.
Start with this line.
We can see that from the first line to the tenth line, it is the same as in the main function
Similarly, let the value of ebp stack;
Then give the value of ebp to esp;
Let esp subtract 0CCh
Stack pressing ebx, esi, edi;
Assign ebp-0Ch to edi, then read down three dword and assign it to 0cch of eax;
Then change edi to the value of ebp.
Next, the same formula,
int z = 0; 002625F5 mov dword ptr [ebp-8],0 //Change the value of ebp-8 position to 0 z = x + y; 002625FC mov eax,dword ptr [ebp+8] //Copy the value of the position of ebp+8 into eax 002625FF add eax,dword ptr [ebp+0Ch] //Then add the value of ebp+0Ch position to eax and store it in eax //ebp+8 and ebp+0Ch happen to be x and y 00262602 mov dword ptr [ebp-8],eax //Assign the value in eax to ebp-8 (that is, z)
00262605 mov eax,dword ptr [ebp-8] take ebp-8 The value of the position is assigned to eax;
00262608 pop edi 00262609 pop esi 0026260A pop ebx pop Three times, pop up three times, that is, pop up edi,esi,ebx The value of,
this is it:
00262618 mov esp,ebp hold ebp to esp
0026261A pop ebp //Pop up ebp (note that the value of ebp will be returned to the original stored value during Pop-Up)
0026261B ret Return to the original memory call Address under instruction Continue execution
Continue after returning:
00261807 add esp,8 //The specific effect of adding esp to 8 is not clear 0026180A mov dword ptr [ebp-20h],eax //Give the value of eax to ebp-20h. //Is to give the value of z just calculated to the position of ebp-20h, that is, c.
Then it returns 0
Here is the familiar formula,
pop three times;
Give the value of ebp to esp;
Pop up esp;
Return to end this function.
If we go on, we'll find
It can also be called elsewhere.
This is because the main function is actually called by other functions.
We can leave this alone.
The rest is about the compiler itself. We can simply understand it at this point.
Well, that's it. Our knowledge about function stack frames is over.
You are welcome to pay attention to me @jxwd, subscribe to the column, and you can continue to see my articles 😀😀
0 basic c language self-study section 2 - preliminary understanding of all the knowledge framework of c language_ jxwd blog - CSDN blog_ c language Framework
C language self-study nanny tutorial - Section 1 - compilation preparation and the first C program_ jxwd blog - CSDN blog