Programming experience (2)
The problem of parameter stack sequence when function call
2004-10-24
Servers: Yang Yanqing E-mail: Blankmanattomdotcom, Http://blog.9cbs.net/blankman/archive/2004/10/24/Programing_experience2.aspx
Yesterday, I suddenly remembered the problem of functional stack order, I discussed with the roommate, and the results found that the results below the compiler were different! So the following analysis:
[Source Procedure]
#include
Void Print (int A, int B, int C) {Printf ("% D / T% D / T% D / N", A, B, C);}
Int main (void)
{
INT P = 0;
Print (p , p, p ); RETURN0;
}
[Call Analysis] In fact, everyone should know this order, I am simple and roughly. The C compiler performs a function call to the parameter stack from the right left. Take the above program, the first stack of parameters is the last "p ", the value of the stack should be 0, and P = 1; then press the stack parameter is the middle " p", stack The value is 2, at this time, P = 2; the last press is the first "p ", the value of the stack should be 2, and P = 3 at this time. So, the output should be "2 2 0". [Existing problems] In TC, TC3, GCC compilation, run the result "2 2 0"; compiled under VC.NET, run the result "2 3 0"; [Problem Analysis] 1, TC3 from the stack to Compilation code for function calling phase: (Usage method tcc -s filename.cpp)
;
; {
; Int P = 0;
;
XOR SI, SI; clear Si, ie P = 0
;
; Print (p , p, p );
;
; Press the last parameter, first press, then add 1 MOV AX, Si; AX = 0
Inc Si
Push AX
; Press the intermediate parameter stack, first plus 1, rear pressure stack Inc Si
MOV AX, Si; AX = 2
Push AX
; Put the first parameter stack, first press, then add 1 MOV AX, Si; AX = 2
Inc Si
Push AX
; Call the Print function call near ptr @ print $ qii
At this point, the analysis work under TC and TC3 is completed, and the result is "2 2 0", it is clear.
2, the assembly code from the stack to the function call phase: ;; int P = 0; 00411B3E MOV DWORD PTR [P], 0; assigning initial value 0, p = 0; Print (p , p, p ) ;;; here involve some addresses and registers, some readers can read, understand them as variables ;; 3 addresses in the text [P] [EBP-0D0H] [EBP -0D4H], EBP and P value in segment program; there is no change, the address can also be understood as a variable.
The following is interpreted; MOV DWORD PTR [P], 0 is to assign the memory assignment at the P address to 0, and the number of assignment cells dword; "There are some registers in the article, just when the operation is performed, it can be understood as temporary Variable ;; operation third parameter 00411B45 MOV EAX, DWORD PTR [P]; EAX = 0 EAX = P00411B48 MOV DWORD PTR [EBP-0D0H], EAX; store the most third parameter value 00411B4E MOV ECX, DWORD PTR [ P]; ECX = 0, ECX = P00411B51 Add ECX, 1; ECX = 100411B54 MOV DWORD PTR [P], ECX; P = 1, P = ECX; operation second parameter 00411B57 MOV EDX, DWORD PTR [P]; EDX = 1 EDX = P00411B5A Add EDX, 1; EDX = 2 00411B5D MOV DWORD PTR [P], EDX; P = 2 P = EDX00411B60 MOV Eax, DWORD PTR [P]; EAX = 2 P = EAX00411B63 MOV DWORD PTR [EBP-0D4H], EAX; store second parameter value; operation first parameter 00411b69 MOV ECX, DWORD PTR [P]; ECX = 2 ECX = P00411B6C Add ECX, 1; ECX = 300411B6F MOV DWORD PTR [ P], ECX; P = 3, P = ECX; start stack 00411b72 MOV EDX, DWORD PTR [EBP-0D0H] The third parameter stack, the value of 000411B78 PUSH EDX00411B79 MOV EAX, DWORD PTR [P]; second parameter stack, value of 300411B7C PUSH EAX00411B7D MOV ECX, DWORD PTR [EBP-0D4H]; first parameter pressure Stack, the value is 200411b83 push ECX; calls the print function 00411b84 Call Print (41100FH) 00411B89 Add ESP, 0ch here, the analysis work under VC.NET is completed, the result is the reason for "2 3 0" is the order of the stack is not standard The order of the stack in C is not the order, or it is not the order, as for why I don't know, if the .NET developers pay attention to this problem, I will return to a post (idiopian dream ^ _ ^). In C99, it is found that there is no clear order in which the stack is not clear.
The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call. EXAMPLE In the function call (* pf [f1 ()]) (f2 ( ), F3 () f4 ()) The functions F1, F2, F3, And F4 May Be Called in Any ORDER. All Side Effects Have To BE BE PF [F1 ()] IS Called. Recommendation] For your versatility, don't write two programs, although there are many exams, I personally don't think it is a master. Previous: Programming experience (1) - "Define string issues (2004-10-13)"
Next: Programming experience (3) - "C, C ] Problems with 1 point 1 (2004-11-23)"
Disclaimer: Original, copyright, please indicate the source if you need to reprint.
Http://blog.9cbs.net/blankman/archive/2004/10/24/programing_experience2.aspx