A parameter reference tip of the Quake source code

xiaoxiao2021-03-06  60

I have seen the following code in the Quake Source code: int VM_CALL (VM_T * VM, INT INSTRUCTION, ...) {va_list argptr; int Arg0; int Arg1; int Arg2; int Arg3; int Arg4; int Arg5; int Arg6;

IF (! VM) {com_error (err_fatal, "vm_call with null vm");}

// COM_PRINTF ("VM_CALL (% i) / n", instruction);

Va_start (argptr, instruction); arg0 = va_arg (argptr, int); arg1 = va_arg (argptr, int); arg2 = va_arg (argptr, int); arg3 = va_arg (argptr, int); arg4 = va_arg (Argptr, int) ); Arg5 = va_arg (argptr, int); arg6 = va_arg (argptr, int); VA_END (Argptr);

Return VM-> Vmmain (instruction, arg0, arg1, arg2, arg3, arg4, arg5, arg6);} I have attracted my interest in VM_CALL (VM_T * VM, int INSTRUCTION, ...) in parameter declaration. ". .. "I have never seen this keyword, I feel very novel. It feels that it is necessary to cheat the compiler, make it not check the parameter type and number of parameter type incorporated after the VM_T * VM, INT INSTRUCTION In other words, regardless of the number of parameters of the function caller, it can be pressed into the stack in one time. So how do the function itself use the parameters in the stack? We still take a look at the macro defined below the system: Typedf char * VA_LIST; #IFDef_m_ix86

#define _intsizeof (N) ((SizeOf (N) SizeOf (Int) - 1) & ~ (SIZEOF (Int) - 1))

#define va_start (AP, V) (AP = (VA_LIST) & V _INTSIZEOF (V)) #define VA_ARG (AP, T) (* (t *) ((AP = _INTSIZEOF (T)) - _INTSIZEOF (T) )) #define va_end (AP) (AP = (va_list) 0)

#elif defined (_M_MRX000)

/ * Use these Types and definitions if generating code for mips * /

#define va_start (AP, V) AP = (VA_LIST) & V SizeOf (V) #define va_end (list) #define va_arg (list, mode) (List = / (char *) (((((((((( INT (__builtin_alignof (mode) <= 4? 3: 7)) & / (__builtin_alignof (mode) <= 4? -4: -8)) sizeof (mode)))) [- 1]

/ * Because of Parameter Passing Conventions IN C: Use mode = int for char, and short type = DOUBLE for FLOAT TYPES USE A POINTER FOR ARRAY TYPES * / # Elif Defined (_M_ALPHA)

We know that the variables used in the function are open in the stack, and the growth direction of the stack is growing from the high address to the low address. If the first variable defined by the function is skipped, we come to the top of the stack of parameters, That is, #define va_start (AP, V) (AP = (VA_LIST) & V _INTSIZEOF (V)) This macro's meaning. # Define VA_ARG (AP, T) (* (t *) ((AP = _intsizeof) ) - _INTSIZEOF (T)) The parameter is removed from the stack from the stack, but not the stack, here should pay attention. But why do you use this way to relatively twisted to pass the parameters? Main reason is Let the code can be compiled on multiple compilers and guarantees the execution effect. The byte length of the original data type defined by each compiler may be different.

转载请注明原文地址:https://www.9cbs.com/read-111831.html

New Post(0)