Sequence of function parameters in C Language

Source: Internet
Author: User

Let's take a look at it through a small program:

# Include

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 [])

{

Fool (100,200,300 );

Return 0;

}

Running result:

X = 100 at [bfe28760]

Y = 200 at [bfe28764]

Z = 300 at [bfe28768]

 

The C program stack bottom is a high address, and the stack top is a low address. Therefore, the above instance can indicate that the function parameter's import sequence to the stack is indeed from right to left. But why? According to the literature, the parameter stack order is related to the specific compiler implementation. For example, in Pascal, parameters are written from left to right into the stack, and some languages can also be specified through modifiers, such as Visual C ++. either method works. Why does the C language need to be right-to-left?

It is further found that Pascal does not support variable length parameters, but C supports this feature, which makes the order of C function parameters in the stack from right to left. The specific cause is that the number of parameters can be dynamically changed because of the advantage of the C-mode parameter entry sequence (from right to left. Stack heap analysis shows that the top parameters of the stack are pressed at the bottom of the stack from left to right. Unless you know the number of parameters, you cannot obtain the leftmost parameter through the relative displacement of the stack pointer. This makes the number of parameters on the left uncertain, which is the opposite of the number of dynamic parameters.

Therefore, C language function parameters adopt the order of inbound Stack from right to left, mainly because they support variable length parameters. In other words, if this feature is not supported, the C language is exactly the same as Pascal and uses the parameter stack mode from left to right.

 

The method used in the C language call Convention is also involved here. The following is a brief introduction:

Differences between _ stdcall and C call conventions (_ cdecl)

 

The C call Convention requires a stack balance before the return, that is, the number of bytes that the parameter has written into the stack should pop up. This is safe.

Note that if the variable parameter vararg is used in the stdcall call convention, the caller must balance the stack like the C call convention.

(1)_ StdcallIt is a Pascal method to clear the C-mode pressure stack. It is usually used in Win32 APIs. functions use the right-to-left mode to clear the stack when they exit. After compiling a function, VC adds an underline prefix to the function name, and adds "@" and the number of bytes of the parameter to the function name. Int F (void * p) --> _ f @ 4 (this function can be referenced in an external assembly language)

In Win32 APIs, there are only a few functions. For example, wspintf uses the C call convention, and all others use stdcall.

(2)C call conventions(Using the _ cdecl keyword) (the C default calling convention) pushes parameters to the stack in the order from right to left, and the caller pushes the parameters to the stack. The memory stack of the transfer parameter is maintained by the caller (because of this, the variable parameter vararg function (such as printf) can only use this call Convention ). In addition, the function name modification conventions are also different. _ Cdecl is the default call Method for C and C ++ programs. Every function that calls it contains the code to clear the stack. Therefore, the size of the executable file generated is larger than that of the call to the _ stdcall function. The function uses the stack pressure mode from right to left. After compiling a function, VC adds an underline prefix to the function name.

(3)_ FastcallThe main feature of calling is fast because it transmits parameters through registers (in fact, it uses ECx and EDX to transmit the first two DWORD or smaller parameters, the remaining parameters are still transmitted from the right to the left pressure stack, and the called function clears the memory stack of the transfer parameter before returning). In terms of the function name modification conventions, it is different from the previous two. _ Fastcall: The function uses registers to pass parameters. After compiling the function, VC adds the "@" prefix to the function name, add "@" and the number of bytes after the function name.

(4)ThiscallApplies only to "C ++" member functions. This pointer is stored in the CX/ECx register, and the parameter is pressed from right to left. Thiscall is not a keyword and cannot be specified by programmers.

(5)Naked call. When 1-4 calls are adopted, the compiler will generate code to save ESI, EDI, EBX, and EBP registers when entering the function if necessary, when you exit the function, the code is generated to restore the content of these registers.

(These codes are called PROLOG and epilog code. Generally, the storage of EBP and ESP is required ).

However, naked call does not generate such code. The naked call is not a type modifier, so it must be used together with _ declspec.

The keywords _ stdcall, _ cdecl, and _ fastcall can be directly added before the function to be output. Their corresponding command line parameters are/GZ,/GD, And/GR. The default status is/GD, Which is _ cdecl.

To fully imitate Pascal's call convention, you must first use the _ stdcall call Convention. As for the function name Modification Convention, you can use other methods to imitate it. Another thing worth mentioning is winapi macro, windows. h supports this macro. It can translate the function into an appropriate call convention. In Win32, it is defined as _ stdcall. You can use the winapi macro to create your own APIs.

In summary, only Pascal calls the stack from left to right, and Pascal cannot use an indefinite number of parameters. The number of parameters is certain.

Briefly summarize the preceding call methods:

Call conventions

Stack clearing

Parameter transfer

_ Cdecl

Caller

Pass through Stack from right to left

_ Stdcall

Function body

Pass through Stack from right to left

_ Fastcall

Function body

From right to left, use register (ECx, EDX) first, and then use Stack

Thiscall

Function body

By default, this pointer is passed through ECx. Other parameters are passed from right to left.

     

 

Related Article

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.