Call agreement through assembly

zhaozj2021-02-16  52

When the function is called, there are various call agreements. They specify the transmission mode of the parameters, whether the parameters can be variable, and who will handle the stack. There are two commonly used calls conventions: C language call conventions and PASCAL language call conventions. You can set the call rules for custom functions in the engineering settings, or you can add keywords or API macro definitions (such as _cdecl, __ stdcall, __ fastcall, winapi, apientry, etc.) when function declarations and definitions. Call agreement. The usage and significance of various call agreements will be described below, and the corresponding assembly code analysis is attached.

1, C language call agreement

When using C language programming, the default uses the C / C language call convention. You can also manually specify, which needs to add the __cdecl keyword when the function declaration is declared. When this convention, the parameter is from right to left, and the number varies. Since the function body cannot know the number of passed parameters in advance, it must be responsible for the stack cleaning by the calling function when using this convention. Since the parameters are variable, this convention is flexible, but the performance is relatively low. The function name in the generated code has a _ (underscore) to prefix it. Example: int __cdecl add (int A, int b) {RETURN (A B);} function call: add (1, 2);

Push 2 Push 1 Call @add; there is also a compiler for the expression of the function to omit the Add ESP, 8; Qing stack

Functional body:

PUSH EBP MOV EBP, ESP SUB ESP, 40H; Function The stack used by the function is 40h (16 * 4), increasing a variable plus 4Byteswin32's granular particle size is 4bytes. Push EBX PUSH ESI Push EDI

LEA EDI, [EBP-40H]; initialization stack space for this function is 0xcccccccc MoV ECX, 10H MOV Eax, 0ccccccccch rep Stos DWORD PTR [EDI]

Return (A B);

MOV EAX, DWORD PTR [EBP 8] Add Eax, DWORD PTR [EBP 0CH]

POP EDI POP ESI POP EBX MOV ESP, EBP; If the ESP is operated in this function, there will be add ESP, 40H CMP ESP, EBP CALL CHKESP, check whether the pop-up ESP pointer is the same as EBP, if different calls Chuest Throw an exception POP EBP

RET

The following figure indicates the use of the stack of the function:

2, Pascal language call agreement

Most of the Windows APIs use the Pascal language call. When using C language programming, if this call is to be adopted, you need to add the __stdcall keyword when the function declares. A WINAPI macro is also defined in the Windows.h header file, which works on the same role. When this convention, the parameters are fixed from the right to left, and the number is fixed. Therefore, the function body itself can know the number of parameters passed, and can clean the stack with a RET N instruction. The sacrificial flexibility is exchanged and the performance is improved. The generated code is a _ (underscore) for a _ (underscore) to prefix, a @ and parameter total byte (decimal) a suffix (number of parameters multiplied by 4). WinAPI Callback Apientry Pascal is a macro definition of __stdcall, and __pascal is a wasteful keyword. Example: INT __STDCALL ADD (INT A, INT B) {RETURN (A B);} Call: Push 2 Push 1 Call _ADD @ 8; Useful function name function body used when connected:; and __cdecl Same, the last line is as follows: RET 8; Qing stack 3, THIS call agreement

The non-static class member function used in C can only be used by the compiler, no corresponding keyword. Under the Intel IA32 architecture, this call agree is the same as the PASCAL language call, except that an additional parameter pointer is transmitted through the ECX register. Cleaning the stack in the function, cannot be used in C, no C's renummation rules, so the non-static member function of the class cannot be used as a callback function. Example: Struct Csum {Int Add (INT A, INT B) {RETURN (A B);}}; function call: csum sum; sum.Add (1, 2);

Push 2 Push 1 Lea ECX, [EBP-4]; ECX stores this pointer call? add @ csum @@ qaehhh @ z; When you repeatedly define a class member function, you can get the name function in the output box: Push EBP MOV EBP, ESP SUB ESP, 44H; Murately used a 4Bytes space for storage this pointer Push EBX PUSH ESI PUSH EDI PUSH ECX LEA EDI, [EBP-44H] MOV ECX, 11H MOV EAX, 0ccccccccch rep Stos DWORD PTR [ EDI] POP ​​ECX MOV DWORD PTR [EBP-4], ECX RETURN (A B);

MOV EAX, DWORD PTR [EBP 8] Add Eax, DWORD PTR [EBP 0CH]

POP EDI POP ESI POP EBX MOV ESP, EBP POP EBP RET 8; Qingnian 4, Quick Call Convention

This call is conventionally used to perform very high performance requirements, the keyword is __fastcall. It requires the parameters in the register to increase the speed. Under the Intel IA32 architecture, this call convention places the parameters of the upper left size and less than 4 bytes (size) of the DWORD, and the rest of the remaining regulations are agreed with the Pascal call. The function name in the generated code has a @ prefix and a @ plus parameter

Total byte (decix) is a suffix. Example: INT __FASTCALL ADD (INT A, INT B, INT C) {RETURN (A B C);} Call: Add (1, 2, 3);

PUSH 3 MOV EDX, 2 MOV ECX, 1 Call @ Add @ 8; the function name used when connecting

Functional body: Push EBP MOV EBP, ESP SUB ESP, 48H; use two variables in [EBP-4], [EBP-8] Push EBX PUSH ESI PUSH EDI PUSH ECX LEA EDI, [EBP-48H] MOV ECX 12h MOV EAX, 0cccccccch rep Stos DWORD PTR [EDI] POP ​​ECX MOV DWORD PTR [EBP-8], EDX; or put EDX, ECX content in MOV DWORD PTR [EBP-4], ECX; in the stack, No speed

RETURN (A B C);

MOV EAX, DWORD PTR [EBP-4] Add Eax, DWORD PTR [EBP-8] Add Eax, DWORD PTR [EBP 8]

POP EDI POP ESI POP EBX MOV ESP, EBP POP EBP RET 4; Qing stack

5, naked adjustment agreement

This method is used when the embedded assembly programmer needs to manually control the call agreed. It has no corresponding keyword, but there is a __DECLSPEC (Naked) to specify this call agreement. It cannot be used for function declarations, which can only be used for function definitions, that is, it can only make the compiler do not generate the stack management code in the function, but call the functioner still requires a previous invocation convention to generate a call function. Code. I have never used this agreement, I hope to have a master supplement.

This article reference: http://www.codeproject.com/cpp/calling_conventions_demystified.asp and the answer on many netizens on 9CBS.

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

New Post(0)