argcargv
Introduction
This header implements the macro argcargv(int argc, char **argv) that
sets its two arguments to the argument count and the argument vector,
respectively, regardless of:
- the
mainfunction having been declared with or without(argc, argv). - the location
argcargvis being called from.
Thus, in a situation where main is declared as main() { ... } and we are in a function foo() called from bar() called from baz() ... called from main(), argcargv() will retrieve argc and argv.
Caveat: valid only for the x86 architecture and needs GNU C.
Source
#ifndef _ARGCARGV_H
#define _ARGCARGV_H 1
#if (!(defined(__i386__) && defined(__GNUC__)))
#error "valid only for GNU C on the x86 architecture"
#endif
#define aa_EBP(r) __asm __volatile( \
"movl %%ebp, %0;" \
: "=g" (r) : \
);
#define aa_XREG(r, a) __asm __volatile( \
"movl (%1), %0;" \
: "=g" (a) : "g" (r) \
);
#define aa_AA(argc, argv, base) __asm __volatile( \
"movl 8(%2), %0;" \
"movl 12(%2), %1;" \
: "=g" (argc), "=g" (argv) : "g" (base) \
);
inline int
__find_main_frame()
{
int base = 0, _base = 0, __base = 0;
aa_EBP(__base);
base = __base;
DOXREG:
aa_XREG(__base, _base);
if (_base == 0x0)
return base;
else {
base = __base;
__base = _base;
goto DOXREG;
}
}
#define argcargv(argc, argv) aa_AA(argc, argv, __find_main_frame())
#endif /* _ARGCARGV_H */