I. Basic Theory of function parameter transfer mechanism
In essence, the function parameter transfer mechanism is a problem where the call function (process) and the called function (process) communicate when the call occurs. There are two basic parameter transfer mechanisms: value transfer and reference transfer. The following describes the functions that call other functions as the main functions. The called functions are called functions.
In the passl-by-value process, the formal parameters of the called function are processed as local variables of the called function, that is, the memory space is opened in the stack to store the values of the real parameters put in by the main function, thus becoming a copy of the real parameters. The feature of value transfer is that any operation of the form parameter of the called function is performed as a local variable, without affecting the value of the real parameter variable of the main function.
During the pass-by-reference process, the form parameter of the called function opens up the memory space in the stack as a local variable, however, the address of the Real Variable put in by the main function is stored. Any operation of the called function on the form parameter is processed as indirect addressing. That is, the address stored in the stack is used to access the real variable in the main function. Because of this, any operation performed by the called function on the form parameter affects
Real variable.
Ii. function parameter transfer mechanism in C Language
In C, value transfer is the only available parameter transfer mechanism. However, as far as I know, due to the influence of pointer variables as function parameters, many friends still think that this situation is passed by reference. This is incorrect. See the following code:
Int swap (int * X, int * Y)
{
Int temp;
Temp = * X; * x = * Y; * Y = temp;
Return temp;
}
Void main ()
{
Int A = 1, B = 2;
Int * P1 = &;
Int * P2 = & B;
Swap (P1, P2)
}
The swap function uses two pointer variables as parameters. When Main () calls swap, it transfers the values of the pointer variables P1 and P2 (that is, the addresses of the variables A and B) by passing the values) in the memory unit opened by SWAp in the stack as the form parameter X and Y. This can be seen from the following Assembly Code (the author adds the annotation ):
22: void main ()
23 :{
......
......
13: int A = 1, B = 2;
00401088 mov dword ptr [ebp-4], 1
00401_f mov dword ptr [ebp-8], 2
14: int * P1 = &;
00401096 Lea eax, [ebp-4]
00401099 mov dword ptr [ebp-0Ch], eax
15: int * P2 = & B;
00401_c Lea ECx, [ebp-8]
0040366f mov dword ptr [ebp-10h], ECx
16: swap (P1, P2 );
004010a2 mov edX, dword ptr [ebp-10h]; parameter P2 value into Stack
004010a5 push edX
004010a6 mov eax, dword ptr [ebp-0Ch]; parameter P1 value into Stack
004010a9 push eax
004010aa call @ ILT + 15 (SWAP) (00401014); call the swap Function
004010af add ESP, 8; clear parameters in the stack
17 :}
When reading the above Code, note that the intel80x86 series CPU processes the stack downward, that is, it generates from the high address unit to the low address unit. From the assembly code above, we can see that before calling swap, main () First presses the value of the real parameter to the stack in the order from right to left, that is, P2 is first pushed to the stack, and P1 is then pushed to the stack. After the call, the main function main () is responsible for clearing the parameters in the stack. Swap will use these variable values into the stack. Below is the swap letter
Data assembly code:
14: void swap (int * X, int * Y)
15 :{
00401030 push EBP
00401031 mov EBP, esp; EBP points to the top of the stack
......
......
16: int temp;
17: temp = * X;
4: int temp;
5: temp = * X;
00401048 mov eax, dword ptr [EBP + 8]; Operation P1 already stored in the stack, set p1
; Into eax
0040104b mov ECx, dword ptr [eax]; Place * P1 into ECx through inter-Register address
0040104d mov dword ptr [ebp-4], ECx; via ECx put * P1 in the temp variable
; Save the ticket. Similar
6: * x = * Y;
00401050 mov edX, dword ptr [EBP + 8]
00401053 mov eax, dword ptr [EBP + 0ch]
00401056 mov ECx, dword ptr [eax]
00401058 mov dword ptr [edX], ECx
7: * Y = temp;
0040105a mov edX, dword ptr [EBP + 0ch]
0040105d mov eax, dword ptr [ebp-4]
00401060 mov dword ptr [edX], eax
8: Return temp;
00401062 mov eax, dword ptr [ebp-4]
9 :}
The assembly code above basically illustrates the principle of the value transfer in C language, but it only transmits the value of the pointer. This article will also discuss how to use the swap function passed by reference. From the analysis of these Assembly codes, we can get the following points:
1. The stack storage area of the process is the main area for communication between the main and called functions.
2. in C language, parameters are pushed from right to left.
3. The stack region structure used by the called function is:
Local variables (such as temp)
Return address
Function Parameters
Low address
High address
4. The main function clears the stack after calling it.
5. the return value of the function is generally included in the register.
Here we need to add a few points: first, the parameter stack method. For internal types, the compiler directly uses the push command because it knows the memory size used by various types of variables. For custom types (such as structure), it uses the source address to the destination (stack zone) the address is transferred to the stack in bytes. The second is why the function return values are generally stored in registers to support interruption. If the function is stored in the stack, it may be overwritten due to interruption. Third, if the return value of a function is very large, it is transferred from the stack to the address unit that stores the return value (the master function provides the address pressure stack to the called function before calling, in order to achieve the purpose of returning. For the second and third parts, the book thinking in C ++ has a better explanation in Chapter 10th. The fourth is an obvious conclusion. If the address of the local variable returned in the called function is meaningless, because the local variable is stored in the stack, the stack will be cleared after the call ends, these addresses become invalid.
Iii. function parameter transfer mechanism in C ++
C ++ has both C value transfer and reference transfer. The value transfer is the same as that of C. Here, the reference transfer is emphasized. As described earlier in this article, the reference transfer is to transfer the variable address to the stack used by the called function. In C ++, the "&" symbol must be used for declaring the reference and passing, but not for calling. The following code uses the swap2 and main functions passed by reference:
Int & swap2 (Int & X, Int & Y)
{
Int temp;
Temp = X;
X = y;
Y = temp;
Return X;
}
Void main ()
{
Int A = 1, B = 2;
Swap2 (A, B );
}
In this case, swap2 accepts the addresses of Two integer variables and returns one of them. The call to swap2 (A, B) in the main function does not determine whether to use the reference transfer or the reference transfer, which is determined by the definition of the swap2 function. The following is the assembly code of the main function:
11: void main ()
12 :{
......
......
13: int A = 1, B = 2;
00401088 mov dword ptr [ebp-4], 1; variable
00401_f mov dword ptr [ebp-8], 2; variable B
14: swap2 (A, B );
00401096 Lea eax, [ebp-8]; sends the offset address of B to eax
00401099 push eax; B offset address pressure Stack
0040109a Lea ECx, [ebp-4]; sends the offset address of a to ECx
00401_d push ECx; press the offset address of a to stack
004010000e call @ ILT + 20 (swap2) (00401019); call the swap Function
004010a3 add ESP, 8; clear parameters in the stack
15 :}
It can be seen that before the main function calls swap2, It offsets B and A from right to left.
Address pressure stack, which is the address of the variable being transferred. In this case, the swap2 function assembly code is:
2: Int & swap2 (Int & X, Int & Y)
3 :{
00401030 push EBP
00401031 mov EBP, ESP
......
......
4: int temp;
5: temp = X;
00401048 mov eax, dword ptr [EBP + 8]
0040104b mov ECx, dword ptr [eax]
0040104d mov dword ptr [ebp-4], ECx
6: x = y;
00401050 mov edX, dword ptr [EBP + 8]
00401053 mov eax, dword ptr [EBP + 0ch]
00401056 mov ECx, dword ptr [eax]
00401058 mov dword ptr [edX], ECx
7: Y = temp;
0040105a mov edX, dword ptr [EBP + 0ch]
0040105d mov eax, dword ptr [ebp-4]
00401060 mov dword ptr [edX], eax
8: Return X;
00401062 mov eax, dword ptr [EBP + 8]; returns X because X is the offset of an external variable.
; Address, so the return is legal
9 :}
It can be seen that swap2 is the same as the swap function assembly code. This is because the previous swap function accepts pointer variables, and the value of pointer variables is the address. Therefore, for swap2 and the previous swap, the function parameters in the stack are all stored in the address, and the operation method in the function is the same. However, for swap2, this address is transmitted by the main function by pressing the offset address of the real variable to the stack -- this
It is a reference transfer. For swap, this address is passed by the main call function by pushing the value of the real variable to the stack-this is a value transfer, but because the real variable is a pointer variable, its value is an address.
The key point here is that it is also the address, the variable address in the reference transfer, and the pointer variable value in the value transfer. I don't want to confuse the passing of pointer variables as function parameters in C language into references if I can clarify this point.
Although X is a local variable, it is valid to return this address in swap2.
Constant reference is often used in C ++, for example, changing swap2:
Swap2 (const Int & X; const Int & Y)
In this case, the content pointed to by the reference address cannot be modified in the function. Specifically, X and Y cannot appear on the left side of "=.
Iv. Conclusion
This article discusses the parameter transfer mechanism of function calls in C and C ++, and illustrates some problems of function return values. In this example, VC ++ 6.0 is used.
Transmission Mechanism Author: Yang Ning Release Date: 2000/11/30