Reputation: 3711
Is there a generic method to get pointer on each argument in C like you would do with a vararg function ?
A special syntax like $1, $2, $3
And if not is there some preprocessor macro that define that ?
If not possible in C I'm also interested in a Objective C solution. I know I can get a selector on current method with _cmd special hidden parameter. Is there some kind of _arg1, _arg2 ?? Also would it be possible to directly point on memory after _cmd ? Is it "safe" to consider parameter pointers are next to each other ?
UPDATE TO MY OWN QUESTION
If I access the frame stack by using some assembler code I can get a hold on the function pointer with ebp right ? So is it possible to access arguments the same way ? Sorry if this is obvious, I don't know much about assembler.
Upvotes: 0
Views: 1502
Reputation: 3264
What is possible but perhaps not entirely useful in your case would be to extract the current and previous stack frame pointers (i e bp register) and, using the standard stack frame structure, determine how many 4 byte (for a 32-bit application) parameter units have been passed in the call to the current routine. You won't be able to determine which units are char, short or long and if two of them together might be a long long/__int64 parameter.
I've thought about this some more. Consider a typical function call "func (a,b)". The calling code unless you have parameters in registers (some x86-32 compiler options and intel recommended for x86-64) the code would turn out like this
; long *esp,*ebp;
push b ; *(--esp)=b;
push a ; *(--esp)=a;
call func ; *(--esp)=return_address_location;
return_address_location:
add esp,8 ; esp+=2; // free memory allocated for passing parameters
Then you come to processing in func
func:
push ebp ; *(--esp)=(long) ebp; // save current ebp <=> current stack frame
mov ebp,esp ; ebp=esp; // create new stack frame in ebp
sub esp,16 ; esp-=4; // reserve space for local variables <=> sizeof(long)*4
(func code ...)
Now when you're in func and you need access to parameters you address them with ebp+2 and ebp+3 (*ebp contains previous ebp, ebp+1 the return address. When you need access to local variables you address them with ebp-4 to ebp-1 (may be over-simplified if they are not all longs and you have some packing option set).
After a while func has done its thing and you need to return:
mov esp,ebp ; esp=ebp; // unreserve space for local variables
pop ebp ; ebp=*(esp++); // restore previous ebp <=> previous stack frame
ret ; eip=*(esp++); // pop return address into instruction pointer
From the first snippet you will also see how the first stack allocation (for passing parameters) is freed right after returning.
A few tips:
Upvotes: 3
Reputation: 215261
If all arguments to a variadic function have the same type (e.g. void *
), you can do something like this:
type nth_arg(va_list ap, size_t n)
{
va_list ap2;
va_copy(ap2, ap);
while (n--) va_arg(ap2, type);
return va_arg(ap2, type);
}
Replace type
with the actual type.
Upvotes: 0
Reputation: 753695
No, there isn't a special way to do that, or any special notation.
I suppose you could define a macro to take each argument and generate a pointer to it (find the Boost preprocessor library); I'm sure I wouldn't want to.
int somefunc(int arg1, char *arg2)
{
int *p_arg1 = &arg1;
char **p_arg2 = &arg2;
...
}
Upvotes: 0
Reputation: 163238
No, the only way you could do this is with the va_list
macros provided in stdarg.h
Upvotes: 2