On Wed, Jul 31, 2002 at 02:42:43PM +0300, Nadav Har'El wrote:
> On Wed, Jul 31, 2002, Alexander V. Karelin wrote about "GNU Assembler #2":
> >...
> > asm("
> > # Set the counter to zero
> > movl $0,%edx
> > # Save the starting point from the params
> > movl 12(%ebp), %ecx
> >...
>
> Maybe I'm missing something here, but why was it so important that you
> write this in assembly-language and not C? Looks like something a simple
> while loop in C would do...
Not quite - you get the parameters as the address of the first one +
number of arguments, and then you call a function which receives that
many arguments, through a function pointer. Here's code that does it,
doing in asm only the required bits:
#include <stdio.h>
typedef void (*pfunc)(void);
void caller2(void* pfn, unsigned long* params, unsigned int nargs)
{
pfunc func = (pfunc)pfn;
while (nargs--)
asm ("pushl %0" ::"g" (params[nargs]));
(*func)();
}
static void callee(int num1, int num2, int num3)
{
printf("callee called: %d %d %d\n", num1, num2, num3);
}
int main()
{
int args[] = {1,2,3};
caller2(callee, (unsigned long*)args, 3);
return 0;
}
BTW, Alexander, your asm could be trivially optimized by the above
method (no need to count up + compare to nargs, just decrememner nargs
and quit on zero) and doesn't work on my machine - program dies with
illegal instruction. You need to tell gcc that you're clobbering
registers in your asm() snippet. info gcc -> c extensions -> extended
asm has the skinny. Thanks to gby for the pointer.
--
http://vipe.technion.ac.il/~mulix/
http://syscalltrack.sf.net/
msg20801/pgp00000.pgp
Description: PGP signature
