Page 1 of 2

passing data from c to asm

Posted: Mon Apr 14, 2003 8:42 pm
by Mastermind
I've got two .o files, one is compiled from c code using gcc and the other is asm code compiled with nasm. They are linked into a .bin file which is the kernel. How do I pass variables from the c to the asm?
What I mean is this:

Code: Select all

------C------
extern someasm();
int task(char *arg);
void dothis(void);

int k_main(void) {
     task("dothis");
}

int task(char *arg) {
     someasm();
}

void dothis(void) {
}
The int task(char*) is supposed to tell the asm function to execute the dothis() function. How do I do this?

Re:passing data from c to asm

Posted: Mon Apr 14, 2003 8:48 pm
by Mastermind
Also, if I send the name of the function (as a string) to the asm function, how would I tell the asm func to run dothis()?
Right now I have to tell the asm what to run, like this:

Code: Select all

jmp     _dothis
;--OR--
call     _dothis
Can I save the func name in a var and do something like:

Code: Select all

jmp     string
, where string is the var containing the c function?

Re:passing data from c to asm

Posted: Tue Apr 15, 2003 12:49 am
by distantvoices
1. calling a c-function from asm: i take NASM as reference:

in c: void do_sthg(void);

in nasm:

EXTERN do_sthg (or EXTERN _do_sthg or EXTERN __do_sthg)

call do_sthg (or _do_sthg or __do_sthg)

When you call an asm from c:
in c: extern int do_sthg(int c, int d);

in nasm:

[GLOBAL do_sthg]
do_sthg:
push ebp
mov ebp,esp
mov ebx,[ebp+8]
mov ecx,[ebp+12]
add ebx,ecx ;(say result is then in ebx)
mov eax,ebx ;(the c function fetches return value from eax usually)
pop ebp
ret

If I have built in some mistakes, sorry for that. But I hope, the principle is clear.

Re:passing data from c to asm

Posted: Tue Apr 15, 2003 11:36 am
by Mastermind
But..., let's say that I wanted to tell the asm to dynamically load funtions. How do I do that? I mean:
The user types "dothis" and the prgm runs "dothis()."
How do I do this?

Re:passing data from c to asm

Posted: Tue Apr 15, 2003 12:24 pm
by Tim
Create a table with function names and pointers to the functions themselves. When a user types a command, search for the command name in the table. Then call the function through the pointer.

For example:

Code: Select all

typedef void (*user_command)(void);
void dothis(void)
{
    printf("doing this\n");
}

void dothat(void)
{
    printf("doing that\n");
}

struct
{
    const char *name;
    user_command function;
} commands[] =
{
    { "dothis", dothis },
    { "dothat", dothat },
};

void docommand(const char *name)
{
    unsigned i;

    for (i = 0; i < sizeof(commands) / sizeof(commands[0]); i++)
        if (stricmp(name, commands[i].name) == 0)
        {
            commands[i].function();
            break;
        }

    if (i == sizeof(commands) / sizeof(commands[0]))
        printf("%s: unknown command\n", name);
}

Re:passing data from c to asm

Posted: Tue Apr 15, 2003 3:11 pm
by Pype.Clicker
an alternative would be to read the symbol table that comes along with the code to find out the address of the function to be called ... however, it would be dangerous because it would mean that you couldn't decide what function can be called and which one can't ...

Re:passing data from c to asm

Posted: Tue Apr 15, 2003 7:55 pm
by Mastermind
That's almost what I have (but it's a little better). But how do I call the function? I have

Code: Select all

"dothis", dothis
but how to load it?

Like:

Code: Select all

load(char *arg1) {
     /* initiates the function whose name
     is stored in char *arg1. */
}

Re:passing data from c to asm

Posted: Tue Apr 15, 2003 8:33 pm
by _mark
a full working example...

Code: Select all

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef int (*fnptr)(void);

struct fntab
{
   char *name;
   fnptr fptr;
};

int test1(void)
{
   printf("test1 called\n");
   return(1);
}

int test2(void)
{
   printf("test2 called\n");
   return(1);
}

int test3(void)
{
   exit(1);
   return(0);
}

struct fntab functions[] =
{
 { "test1", test1 },
 { "test2", test2 },
 { "quit",  test3 },
 { "exit",  test3 },
 { "", 0 }
};

main()
{
   int     i;
   char fname[255];

   printf(">");
   while (gets(fname))
   {
      i=0;
      while ( functions[i].name[0] != '\0' )
      {
         if ( strcmp(fname, functions[i].name) == 0 )
         {
            functions[i].fptr();
            break;
         }
         i++;
      }
      printf(">");
   }
   return(1);
}
Good luck
_mark()

Re:passing data from c to asm

Posted: Wed Apr 16, 2003 10:23 am
by Mastermind
So functions.fptr(); is what you do to call the function in functions? Thanks!!

Oh yeah... Another question. The code included stdlib.h. Is this absolutely necessary to make the functions[1].fptr() work?

Re:passing data from c to asm

Posted: Wed Apr 16, 2003 10:37 am
by Whatever5k
Mastermind wrote: So functions.fptr(); is what you do to call the function in functions?

Yes - fptr is a pointer to a function.
Oh yeah... Another question. The code included stdlib.h. Is this absolutely necessary to make the functions[1].fptr() work?

No, this is a feature of C. Actually, I don't know if stdlib.h is needed at all, I cannot see any function that needs stdlib to be included.

Re:passing data from c to asm

Posted: Wed Apr 16, 2003 8:31 pm
by _mark
The syscall exit() is defined in stdlib.h.

_mark()

Re:passing data from c to asm

Posted: Thu Apr 17, 2003 3:06 am
by distantvoices
isn't this exit() called automatically at the end of the program thus ending the entire process?

further, when you say exit(n) -- is there really need for a return clause?

Re:passing data from c to asm

Posted: Thu Apr 17, 2003 3:25 am
by Whatever5k
mark, you're right - I didn't see the exit() in test3.
isn't this exit() called automatically at the end of the program thus ending the entire process?
Yes, if you have a program like

Code: Select all

int main(void)
{
  print_something();
  return 0;
}
the system will exit the process automatically, since main() is not the actual entry point, but start, which looks something like this (very simplified):

Code: Select all

void start(void)
{
   current->root(); /* call the main function */
   exit_proc(current);
}
further, when you say exit(n) -- is there really need for a return clause?
That's right, too. Everything after the exit() will not have a effect.

Re:passing data from c to asm

Posted: Thu Apr 17, 2003 6:45 am
by _mark
further, when you say exit(n) -- is there really need for a return clause?
In test3() I just added the return() after exit() to avoid a compiler warning. Since the compiler would generate a return anyway there is no code size penalty for adding it.

_mark()

Re:passing data from c to asm

Posted: Thu Apr 17, 2003 10:28 am
by Tim
You can avoid the warning after exit() if exit() is declared properly. IIRC in gcc it's something like:

Code: Select all

void exit(int) __attribute__((noreturn));