passing data from c to asm

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Mastermind

passing data from c to asm

Post 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?
Mastermind

Re:passing data from c to asm

Post 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?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:passing data from c to asm

Post 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.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Mastermind

Re:passing data from c to asm

Post 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?
Tim

Re:passing data from c to asm

Post 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);
}
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:passing data from c to asm

Post 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 ...
Mastermind

Re:passing data from c to asm

Post 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. */
}
_mark

Re:passing data from c to asm

Post 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()
Mastermind

Re:passing data from c to asm

Post 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?
Whatever5k

Re:passing data from c to asm

Post 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.
_mark

Re:passing data from c to asm

Post by _mark »

The syscall exit() is defined in stdlib.h.

_mark()
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:passing data from c to asm

Post 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?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Whatever5k

Re:passing data from c to asm

Post 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.
_mark

Re:passing data from c to asm

Post 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()
Tim

Re:passing data from c to asm

Post 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));
Post Reply