have a look at stdarg.h in kernel 0.01 linux for an idea - va_start is a macro that initializes ap with as an increment starting at the first argument plus its size (rounded to machine word size); va_arg sets ap as the type given, and increments further the ap in the same way (rounding the type to machine words)
#define __va_rounded_size(TYPE) \
( ( (sizeof (TYPE) + sizeof (int) - 1) / sizeof (int) ) * sizeof (int) )
#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE)) ))