The stdarg. h file contains the following macro definitions:
#include <vadefs.h>#define va_start _crt_va_start#define va_arg _crt_va_arg#define va_end _crt_va_end#endif /* _INC_STDARG */
It is defined in vadefs. h:
# DEFINE _ intsizeof (N) (sizeof (n) + sizeof (INT)-1 )&~ (Sizeof (INT)-1) # define va_start (AP, V) (AP = (va_list) & V + _ intsizeof (v )) // The first optional parameter address # define va_arg (AP, t) (* (T *) (AP + = _ intsizeof (t)-_ intsizeof (t ))) // next parameter address # define va_end (AP) (AP = (va_list) 0) // set the pointer to invalid
In the process, stack addresses are allocated from high to low. when a function is executed, the parameter list is pushed into the stack, the high address of the stack, the return address of the function, and the Execution Code of the function, during the stack import process, the stack address is constantly decreasing. Some hackers modify the function return address in the stack and execute their own code to execute their own inserted code segments.
In short, the distribution of functions in the stack is: address from high to low, in turn: function parameter list, function return address, function Execution Code segment.
In the stack, the distribution of each function is in reverse order. that is, the highest part of the last parameter in the list, and the first parameter in the lowest part of the list address. the parameter distribution in the stack is as follows:
Last Parameter
Second to last parameter
...
First Parameter
Function return address
Function Code segment
Code example: Here is a variable parameter addition Function
# Include <stdio. h> # include <stdlib. h> # include <stdarg. h>/* function: Variable Parameter summation * parameter: Number of numcount parameters... variable sum parameter * return value: Sum of the added parameters and */INT sum (INT numcount ,...) {int result = 0; // calculation result va_list AP; // initialize the pointer to the variable parameter list (typedef char * va_list) va_start (AP, numcount ); // pay the address of the first variable parameter to the AP, that is, the AP points to the start of the variable parameter list for (INT I = 0; I <numcount; I ++) result + = va_arg (AP, INT); // obtain the value of the first variable parameter, and move the AP pointer up to a _ intsizeof (INT), that is, to the address of the next variable parameter. va_end (AP); // set null AP, that is, AP = (void *) 0; return result;} int main (void) {printf ("20 + 15 + 3 + 8 = % d \ n", sum (, 8); System ("pause"); Return 0 ;}