Visual C ++ function call mode

zhaozj2021-02-16  53

Visual C function call mode

We know that there are several call methods to class, Pascal. C-type C is default unless special declarations. The two are different. Here we use examples:

1. __cdecl: C and C Default call mode example: Void INPUT (INT & M, INT & N); / * Equivalent to void __cdecl INPUT (INT & M, INT & N); * / The following is the corresponding assembly code: 00401068 Lea Eax , [EBP-8]; Take the [EBP-8] address (EBP-8), save the EAX 0040106B Push Eax; then press the 0040106C LEA ECX, [EBP-4]; take the [EBP-4] address (EBP- 4), save the ECX 0040106F PUSH ECX; then press the address (0040100A); then call the input function 00401075 Add ESP, 8; recovery stack From the process of calling the input function from the above: Before calling this function, press EBP-8, then press EBP-4, then call function input, and finally the Input function call is completed, use the ESP 8 recovery stack. It can be seen that the default function modification _cdecl in the C language is called, and the parameter stack is performed by the main call function and the stack is restored. Let's take a look at: What is address EBP-8 and EBP-4? In the VIEW of the VC, select Rebug Windows, then select Registers, display register variable, and then enter the value of EBP-8 and EBP-4 value (or directly input EBP-8 and -4) below the Memory below. Look at what the value is actually stored in these two addresses, it is actually the address of the variable N (EBP-8), M's address (EBP-4), which can be seen: in the main call function The stack and the order is from right to left. In addition, since the argument is a reference to the corresponding variable, it is also proved that the address (similar to pointer) is actually referenced. Summary: In C or C language calls, the default function modification _cdecl is made by the main call function, and the stack is restored. The stack order of the arguments is from right to left, and finally the stack recovery is made by the master function. Since the main adjustment function management stack, the changeable function can be implemented. In addition, the naming modification method is to add an underline (_) before the function.

2. WinAPi (actually PASCAL, CALLBACK, _STDCALL) example: Void WinAPI INPUT (INT & M, INT & N); Look at the assembly code of the corresponding call: 00401068 Lea Eax, [EBP-8] 0040106B Push EAX0040106C Lea ECX, [ EBP-4] 0040106F PUSH ECX00401070 Call @ ilt 5 (0040100A) From the above-described process of calling the input function: Before calling this function, first press the EBP-8, then press EBP-4, then Call the function input, after calling the function input, there is no corresponding stack recovery (for other function calls, so I have not listed) The following is listed below the assembly code of the input function itself: (actually this function is not big, but compiling The example is still bigger, everyone can only look at the front and after, the middle code has nothing to do with this example)

39: void WINAPI Input (int & m, int & n) 40: {00401110 push ebp00401111 mov ebp, esp00401113 sub esp, 48h00401116 push ebx00401117 push esi00401118 push edi00401119 lea edi, [ebp-48h] 0040111C mov ecx, 12h00401121 mov eax, 0CCCCCCCCh00401126 rep Stos DWORD PTR [EDI] 41: Int S, I; 42: 43: While (1) 00401128 MOV Eax, 10040112D Test Eax, EAX0040112F JE Input 0C1H (004011D1) 44: {45: Printf ("/ NPLEase Input The first Number M: "); 00401135 Push Offset String" / NPLEASE INPUT The First Number M "... (004260B8) 0040113A Call Printf (00401530) 0040113F Add ESP, 446: Scanf ("% D ", & M); 00401142 MOV ECX , dword ptr [ebp 8] 00401145 push ecx00401146 push offset string "% d" (004260b4) 0040114B call scanf (004015f0) 00401150 add esp, 847: 48: if (m <1) continue; 00401153 mov edx, dword ptr [ EBP 8 ] 00401156 cmp dword ptr [edx], 100401159 jge Input 4Dh (0040115d) 0040115B jmp Input 18h (00401128) 49: printf ( "/ nPlease input the first number n:"); 0040115D push offset string "/ nPlease input the first number n "... (0042608c) 00401162 call printf (00401530) 00401167 add esp, 450: scanf ("% d ", & n); 0040116A mov eax, dword ptr [ebp 0Ch] 0040116D push eax0040116E push offset string" % D "(004260B4) 00401173 Call scanf (004015f0) 00401178 Add ESP, 851: 52: IF (n <1) Continue; 0040117B MOV ECX, DWORD PTR [EBP

0ch] 0040117E CMP DWORD PTR [ECX], 100401181 JGE INPUT 75H (00401185) 00401183 JMP INPUT 18H (00401128) 53:54: for (i = 1, s = 0; i <= n; i ) 00401185 MOV DWORD PTR [EBP-8], 10040118c MOV DWORD PTR [EBP-4], 000401193 JMP Input 8EH (0040119E) 00401195 MOV EDX, DWORD PTR [EBP-8] 00401198 Add EDX, 10040119B MOV DWORD PTR [EBP-8], EDX0040119E MOV EAX, DWORD PTR [EBP 0CH] 004011A1 MOV ECX, DWORD PTR [EBP-8] 004011A4 CMP ECX, DWORD PTR [EAX] 004011A6 JG INPUT 0A3H (004011B3) 55: S = S I; 004011A8 MOV EDX , DWORD PTR [EBP-4] 004011AB Add Edx, DWORD PTR [EBP-8] 004011AE MOV DWORD PTR [EBP-4], EDX004011B1 JMP INPUT 85H (00401195) 56: IF (m> = s) 004011B3 MOV EAX, DWORD PTR [EBP 8] 004011B6 MOV ECX, DWORD PTR [EAX] 004011B8 CMP ECX, DWORD PTR [EBP-4] 004011BB JL Input 0afh (004011BF) 57: Break; 00401 1BD JMP INPUT 0C1H (004011d1) 58: Else59: Printf ("M

Obviously, the stack is restored. Due to the 32-bit C , the variable address is 4 bytes (INT is also 4 bytes), so two addresses are 8 bytes. It can be seen that the stack is responsible for the stack in the main modulation function, and is responsible for restoring the stack in the called function. Therefore, the changeable function cannot be achieved because the called function cannot know the number of stacks in advance, but can be done in the main adjustment function, because the number of parameters is determined by the main adjustment function. Let's take another look, the two addresses of EBP-8 and EBP-4 actually store what values, the EBP-8 address is N, and EBP-4 is stored at the value of M. The description is also from right to left stack, perform parameter delivery. Summary: Responsible in the main adjustment function, responsible for popping the parameters in the stack in the called function and is responsible for restoring the stack. Therefore, the variable-gate function cannot be realized, and the parameter transmission is from right to left. In addition, the naming modification method is to add a downline (_) before the function, there is a symbol (@) after the function name, and the number of items accounting in the parameter in the parameter list (10), such as: Void INPUT (INT & M, INT & N), is modified: _input @ 8 For most API functions, the window message handler is used in callback, so before calling, the Motor will press the stack first, then the API function restores the stack. Such as: Push Edx Push EDI PUSH EAX PUSH EBX CALL GETDLGITEMTEXTA You can think about what these registers are stored?

Reference: The MSDN example is a Win32 Console disassembly code under Debug mode under VC6.0.

转载请注明原文地址:https://www.9cbs.com/read-27988.html

New Post(0)