Sequence of function parameters in C language-fangzhen-Blog Park

Source: Internet
Author: User

Let's take a look at a small program:

1234567891011121314 #include <stdio.h> void foo(int x, int y, int z){    printf("x = %d at [%X]\n", x, &x);    printf("y = %d at [%X]\n", y, &y);    printf("z = %d at [%X]\n", z, &z);} int main(int argc, char *argv[]){    foo(100, 200, 300);    return 0;}

Operation Result:

123 x = 100 at [22FF10]y = 200 at [22FF14]z = 300 at [22FF18]


c The bottom of the program is high address, the top of the stack is a low address, so the above example can show that the function parameters in the stack order is really right-to-left. But why in the end? We've been through it. It is found that the parameter in the stack sequence is related to the implementation of the specific compiler. For example, the Pascal language parameters are left-to-right in the stack, and some languages can also be specified by modifiers, such as Visual C + +. That is, both ways, why C language to choose from right to left?

It is further found that the Pascal language does not support variable length parameters, while the C language supports this feature, which makes the C function parameters in the stack order from right to left. The specific reason is: the C-mode parameter in the stack order (right-to-left) The advantage is that you can dynamically change the number of parameters. The stack analysis shows that the front parameters are pressed on the bottom of the stack, from left to right. Unless you know the number of arguments, the leftmost parameter cannot be obtained by relative displacement of the stack pointer (it is easy to locate the parameters near the stack pointer). This becomes the number of left parameters is indeterminate, just as the number of dynamic parameters in the opposite direction.

Therefore, the C language function parameters are in the order of right-to-left stacking, the main reason is to support variable-length parameter forms. In other words, if this feature is not supported, the C language is exactly the same as Pascal, with left-to-right arguments in the stack.

Here in fact also involves the use of the calling convention in the C language, the following simple introduction:

The difference between __stdcall and the C calling convention (__cdecl)

C calling convention to make a stack balance before returning, that is, how many bytes the parameter is in the stack, and how many bytes will pop up. It's safe.

One thing to note: The stdcall calling convention, if you take an indeterminate argument, that is, vararg, is the same as the C calling convention, which is called by the caller for stack balancing.

(1)_stdcall is a Pascal way to clean up the C-mode compression stack, usually used in the Win32 API, the function takes a right-to-left stack, and empties itself at the exit. After the VC compiles the function, it adds an underscore prefix to the function name, followed by the function name with the "@" and the number of bytes of the parameter. int f (void *p)-->> [email protected] (the function can be referenced in an external assembly language using this name)

In the WIN32 API, only a few functions, such as the wspintf function, are in the C calling convention, and others are stdcall

(2)c calling convention (that is, with the __CDECL keyword description) (the C default calling convention) in the right-to-left order to press parameters into the stack, the caller will pop up the stack parameters. The memory stack for routing parameters is maintained by the caller (because of this, functions that implement variadic vararg (such as printf) can only use the calling convention). In addition, there are differences in function name adornment conventions. _cdecl are the default calling methods for C and C + + programs. Each function that calls it contains the code that empties the stack, so the resulting executable file size is larger than the call to the _stdcall function. The function uses a right-to-left compression stack. When a VC compiles a function, it will precede the function name with an underscore prefix.

(3) The main feature of the__fastcall call is fast because it transmits the parameters via registers (in fact, it transmits the first two double words (DWORD) or smaller parameters with ECX and edx, and the remaining parameters are still transferred from right to left. The called function cleans the memory stack of the routing parameters before returning, and it differs from the previous two in terms of the function name adornment convention. The function of the __fastcall method takes the register pass parameter, the VC compiles the function to precede the function name with the "@" prefix, after the function name adds "@" and the parameter the number of bytes.

(4)ThisCall applies only to "C + +" member functions. This pointer is stored in the CX/ECX register, and the parameters are pressed from right to left. ThisCall is not a keyword and therefore cannot be specified by the programmer.

(5)nakedcall. When using the 1-4 calling convention, if necessary, the compiler generates code to hold the ESI,EDI,EBX,EBP register when the function is entered, and the contents of these registers are generated when the function exits.

(These codes are called Prolog and Epilog code, and in general, EBP,ESP is required for saving).

But naked call does not produce such a code. Naked call is not a type modifier and must be used in conjunction with _DECLSPEC.

The keywords __stdcall, __cdecl, and __fastcall can be added directly before the function to be output. Their corresponding command-line arguments are/gz,/gd, and/gr, respectively. The default state is/GD, which is __cdecl.

To completely imitate the Pascal calling convention, you must first use the __stdcall calling convention, and as for the function name decoration conventions, you can imitate them by other means. Also worth mentioning is the WINAPI macro, which Windows.h supports the macro, which translates the function into the appropriate calling convention, which is defined as __stdcall in WIN32. Use the WINAPI macro to create your own APIs.

In fact, only Pascal calls the contract from left to right into the stack. And Pascal can not use the number of indefinite arguments, the number of parameters is certain.

Briefly summarize the above several invocation methods:

calling convention

stack clear

parameter passed

__cdecl

caller

right-to-left, passing through the stack

__stdcall

function body

right-to-left, passing through the stack

__fastcall

function body

right-to-left, using registers (ECX,EDX) first, and then using stacks

thiscall

function body

this pointer passed by ECX by default, other parameters from right to left into the stack

Sequence of function parameters in C language-fangzhen-Blog Park

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.