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/

Attachment: msg20801/pgp00000.pgp
Description: PGP signature

Reply via email to