This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Calling C functions in Assembly from C


Hi all,
   I have a couple of questions around the use of
assembly to call C functions. I am building a JVM for
school (GPL, if anyone wants to take a look
http://www.cs.rit.edu/~pal6640). 

In order to build the Java -> native code bridge I
have to be able to invoke C functions without know
what arguments it takes. So I have a function pointer
and a variable size list of arguments. I need to
invoke the functions with the argument list. The only
way that I could think of to do this was to use
assembly. In assembly I can just push the arguments
onto the stack one by one then call the function. So
what I'm doing is calling C functions from C by using
assembly. 

My first question is, does anyone know of a better way
to do this?

My second question is, if not, is there a clean
portable way to do this using GCC? I know clean and
portable don't exactly belong in the same sentence
with assembly, but I am hoping that calling C
functions from assembly may be a common problem and
maybe some cross platform macros have been developed
to do this, something like PUSH( arg ) and INVOKE(
func ).

My code was working on linux/x86 sun/sparc and
cygwin/x86, but now it only works on x86 (as that is
the only asm I've code so far). However, it won't work
on linux/x86 and cygwin/x86 with the same code.

My invoke_native method follows the email. I hope it
still readable after being put through the Yahoo mail 
grinder.

On linux if I pop the call stack after the method
returns, I get a segfault. On windows, if I don't pop
the call stack, it seg faults. Depending on which
system I run it on, it segfaults in either case. I'm
also not sure I'm doing everything I should be to
ensure that the calling environment doesn't get
clobbered. I put all the registers it would take into
the clobbers notation on the assembly call
instruction.

Any help appreciated, with above questions or with
assembly in general (insights, tips, best practices
etc).

I am using gcc version 3.1.1 20020710 (prerelease) on
cygwin and gcc version 3.1.1 20020531 (Debian
prerelease) on linux.

I have read through the GCC : Extended ASM page and
various other web references.

Lastly, if this question would be more appropriate for
a different list, pointers to the correct list would
also be appreciated.

thank you,
Paul Lorenz

(subscribed to gcc-help digest version)

=============================================
void invoke_native( jvm_thread_t *jvm_thread, method_t
*method )
{
	void *fp = method->native_code;
	stack_frame_t *stack_frame = list_top(
jvm_thread->jvm_stack );
	int i;
	char *desc;
	u4 ret_value;

	push_stack_frame( jvm_thread, method );

	/**
	 * Do NOT put any functions calls in the middle of
the assembly
	 * as it will screw up the function call you are
trying to 
	 * build
	 **/
	for ( i = method->args_size - 1; i >= 0; i-- )
	{
		asm( "pushl %0": /* no outputs */: "g"
(stack_frame->op_stack[i]) );
	}

	asm( "call *%0" : /* no outputs */ : "g" (fp) :
"%eax", "%ecx", "%edx", "%cc", "memory" );
	asm ( "movl %%eax, %0" : "=g" (ret_value) : /* No
inputs */ );

	/* On windows, this statement is required otherwise
it
	 * segfaults. Sometimes it segfaults anyway (on
different systems)
	 * On linux, this statement is prohobited, otherwise
	 * it segfaults. */
	//asm ( "addl %0, %%esp" : /* No outputs */ : "g" (
method->args_size * 4) );

	pop_stack_frame( jvm_thread );

	desc = method->descriptor;
	while ( *(desc++) != ')' ) {}

	//printf( "%c\n", *desc );

	if ( *desc == 'V' )
	{
		//printf( "Void return\n" );
	}
	/* If it is a object or array refence, or is an int
*/
	else if ( *desc == 'L' || *desc == '[' || *desc ==
'I' )
	{
		//printf( "Return value %lu\n", ret_value );
		stack_push_4( stack_frame, ret_value );
	}
	else
	{
		printf( "Don't know how to handle that return type
yet" );
		printf( "(in invoke_native)\n" );
		exit( -1 );
	}

	//printf( "Finished native call\n" );
}

=====================================================================================================================

__________________________________________________
Do You Yahoo!?
Yahoo! Autos - Get free new car price quotes
http://autos.yahoo.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]