当前位置:网站首页>[C language - function stack frame] analyze the whole process of function call from the perspective of disassembly

[C language - function stack frame] analyze the whole process of function call from the perspective of disassembly

2022-06-11 08:57:00 BaconZzz

Preface

Beginner programming , Mostly in doubt :

How is the function called ? How local variables are destroyed when they are out of scope ? How to pass parameters of a function ? Why can't the formal parameter of a function be changed to an actual parameter …

today , Let's look at it from the perspective of disassembly “ Function stack frame creation and destruction ” , To savor After decades of programming precipitation, it is precise and ingenious

1. Function stack frame (stack frame)

C In the programming of , Independent functions are often abstracted as functions , You can also say C The basic unit of a program is a function

Function stack frame , During function call , In the call stack of the program (call stack) The space opened up in

To learn about its Definition and function

Definition :
Stack frame is also called Process activity records , It's the compiler that implements the process / A data structure for function calls .

effect :

  1. Make room for the called function

  2. It can store

  • Function parameter 、 Function return value
  • Temporary variable ( Local variables in functions, etc )
  • Context information ( Registers that need to remain unchanged before and after a function call )

2. Function stack frame preparation knowledge

2.1 Stack

Stack (stack), A kind of “ Special containers ”, You can put data : Pressing stack (push), The data Push the In the stack ; Out of the stack (pop), Push the elements that have been pushed onto the stack eject

  • One rule to follow : First put the data into the stack and then out of the stack (First In Last Out)
  • Memory usage in the stack , Always start with the high address

You know :

Stack is a with the above characteristics Dynamic memory area Pressing the stack increases the stack , Out of stack makes stack smaller

2.2 Related registers and assembly instructions

Related registers

eax: General registers , Keep temporary data , Often used to return a value
ebx: General registers , Keep temporary data
ebp: Bottom of stack register
esp: Top register
eip: Instruction register , Save the address of the next instruction of the current instruction

Assembly instruction

mov: Data transfer instruction
push: Data on the stack , meanwhile esp The stack top register will also change
pop: The data pops up to the specified location , meanwhile esp The stack top register will also change
sub: Subtraction command
add: Add command
call: Function call ,1. Press in return address 2. Go to the objective function
jump: By modifying the eip, Go to the objective function , To call
ret: Restore return address , Push the eip, similar pop eip command

3. Parsing function stack frame creation and destruction

Function stack frame creation and destruction , esp and ebp It's very important !

Dissect this example :

#include<stdio.h>
int Add(int x, int y)
{
    
	int z = 0;
	z = x + y;
	return z;
}
int main()
{
    
	int a = 0;
	int b = 0;
	int ret = 0;
	ret = Add(a, b);
	printf("%d\n", ret);
	return 0;
}

F10 Debug

3.1 call Stack

“ debugging ” – “ window ” – “ call Stack ” – Right click to check “ Display external code ”

call Stack , Let us see clearly The logic of function call

 Insert picture description here

You can see , Calling main function Before , Several functions have been called ; main function Be being invoke_main() call

In that case ,invoke_main() It should also have its own stack frame ,main() 、 Add() There are —— Each function stack frame has its own ebp and esp maintain

Yes main The function before the function will not be discussed too much today

3.2 Function stack frame !

How to open up the memory space of the function ?

adopt esp and ebp Movement of two pointers , Maintain a space ( The space between two pointers )

Now debug to main The first line at which the function starts execution , Right click to go to disassembly

Function stack frame creation

004F18B0  push        ebp  //push ebp The value in (invoke_main Of ebp)
004F18B1  mov         ebp,esp  // hold esp(invoke_main Of esp) Put the value of ebp in 
004F18B3  sub         esp,0E4h  //esp-0E4h
004F18B9  push        ebx  // Register ebx Value stack of ,esp-4
004F18BA  push        esi  // Register esi Value stack of ,esp-4
004F18BB  push        edi  // Register edi Value stack of ,esp-4
004F18BC  lea         edi,[ebp-24h] // stay edi Load valid addresses in [ebp-24h]
004F18BF  mov         ecx,9  
004F18C4  mov         eax,0CCCCCCCCh  
004F18C9  rep stos    dword ptr es:[edi]  
  1. push Of the previous function ebp
  2. Calculate the... Of this function ebp and esp
  3. push ebx esi edi Values in the three registers , Because they may be modified in subsequent execution , So save it first , So that when you exit the function, you can restore
  4. Initialize the stack frame space of the function
    The meaning of the last three instructions : take from edi Start , Down 9 The content of a space Initialize to 0xcc cc cc cc

Execution of core code ( Including the destruction of function stack frames )

	int a = 3;
009218D5  mov         dword ptr [ebp-8],3  // hold 3 Deposit in [ebp-8] It's about ,[ebp-8]  The position of is a Variable 
	int b = 4;
009218DC  mov         dword ptr [ebp-14h],4  // hold 4 Deposit in [ebp-14h] It's about ,[ebp-14] The position of is b Variable 
	int ret = 0;
009218E3  mov         dword ptr [ebp-20h],0  // hold 0 Deposit in [ebp-20h] It's about ,[ebp-20h] The position of is ret Variable 
// call Add function 
	ret = Add(a, b);
// Function arguments : Save to register , Again push Register value 
009218EA  mov         eax,dword ptr [ebp-14h]  // hold b Put it in eax in 
009218ED  push        eax  //push eax
009218EE  mov         ecx,dword ptr [ebp-8]  // hold a Put it in ecx in 
009218F1  push        ecx  //push ecx

// Jump to the called function 
009218F2  call        009210B4 //push The address of the next instruction executes the function call logic 
							  //( Is to directly start the function after the function is called call The next statement of begins execution )


---------------- I am leaving main---------------



// here F11 Get into Add
int Add(int x, int y)
{
    
//
00921770  push        ebp  // preservation main Of ebp,esp-4
00921771  mov         ebp,esp  // hold main Of esp Assign to ebp, produce Add Of ebp
00921773  sub         esp,0CCh  //esp-0CCh, Calculation Add Of esp
00921779  push        ebx  //push  register 
0092177A  push        esi  //push  register 
0092177B  push        edi  //push  register 

// Initialize stack frame 
0092177C  lea         edi,[ebp-0Ch]  
0092177F  mov         ecx,3  
00921784  mov         eax,0CCCCCCCCh  
00921789  rep stos    dword ptr es:[edi]  
0092178B  mov         ecx,92C003h  
//
00921790  call        0092131B  
	int z = 0;
00921795  mov         dword ptr [ebp-8],0  // hold 0 Deposit in [ebp-8] The address of , establish z Variable 
	z = x + y;
0092179C  mov         eax,dword ptr [ebp+8]  // hold [ebp+8] Place the value of the ( It's just before push The parameter of ) Deposit in eax in 
0092179F  add         eax,dword ptr [ebp+0Ch]  // to eax Plus [ebp+0Ch] Place the value of the ( It was also the previous push The parameter of )
009217A2  mov         dword ptr [ebp-8],eax  // hold eax( Using the result of formal parameter calculation ) Put it in [ebp-8](z The position of the variable ) It's about ,
	return z;
009217A5  mov         eax,dword ptr [ebp-8]  // hold [ebp-8](z) Put the value in the register , Bring back the return value through the register 
}
// The destruction Add The stack frame 
009217A8 pop edi //pop edi,esp+4
009217A9 pop esi //pop esi,esp+4
009217AA pop ebx //pop ebx,esp+4
009217AB mov esp,ebp // hold ebp Assign to esp, Equivalent to recycling Add The stack frame 
009217AC pop ebp //pop ebp, eject ebp And put it in ebp, The value at the top of the stack is main Of ebp,esp+4, skip Add Of ebp, Another maintenance start main Function 
009217AD ret // First pop once ( The value at the top of the stack is call The address of the next instruction of the instruction ), Again esp+4, Jump to the “call Next instruction for ” The address of , Carry on 



----------- Back to main----------------



// Now it's back call The next instruction of the instruction begins to execute ...
009218F7  add         esp,8  //esp+8, Destroy previous push The parameter of a and b

009218FA  mov         dword ptr [ebp-20h],eax // hold eax Put the value of ret Variable , here eax What's in store is Add The return value of 

summary

Create stack frame

  1. push Of the previous function ebp
  2. Calculate the... Of this function ebp and esp
  3. push ebx esi edi Values in the three registers
  4. Initialize the stack frame space of the function

Destroy stack frame

  1. Destroy the called function stack frame ——mov esp,ebp
  2. Pointer transpose —— Put the called function ebp esp Set as the main function ebp esp

Call function

  1. The ginseng —— Put the arguments in the register and press the stack
  2. call—— First push call The address of the next instruction , Then enter Add
  3. Create stack frame
  4. Core code —— Example of Add utilize ebp Address offset to access the formal parameter , This is it. Formal parameter access
  5. Save return value —— Put the calculation result in the register , Go back to the main function and use
  6. Destroy stack frame —— Destroy the stack frame of the called function , And then the called function ebp esp Set as the main function ebp esp
  7. Jump back call The address of the next instruction

expand :
In fact, when returning the built-in type of the object , Generally, the return value is brought back through the register , Returns a larger object , One
Generally, it will open up a space in the stack frame of the main calling function , Then put the address of this space , Implicitly passed to the called function , In the modulated function
Find the reserved space in the calling function through the address , Save the return value directly to the of the calling function .

原网站

版权声明
本文为[BaconZzz]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110845565435.html