JacobM
JacobM

Reputation: 11

How do you execute a C program from within a x86 assembly program?

I am new to this assembly scene and I was reading a tutorial on creating a simple OS here: http://mikeos.berlios.de/write-your-own-os.html since I really do not want to figure out assembly is there a way that in the middle of the assembly code that it could execute C code.

If you could please give step by step directions on how this can be executed since I am a beginner. I am running Ubuntu 13.10 if that helps at all.

Edit

I apoligise for not being clear. What I would like to do is in the middle of an assembly program, for it to stop executing the assembly commands and instead to start running a C file that has the actual code that I would like to use on my OS such as the scanf and printf functions.

I am running into some trouble. If you could provide a link to a tutorial that just gets me to the point where I have a hello world OS. I can edit the C code from there and be on my way, thanks!

Upvotes: 0

Views: 2336

Answers (1)

user26347
user26347

Reputation: 604

Ok, step by step instructions, they work on any platform, which is good because you didn't specify what platform you were on:

1) Get a C compiler, in this example I will use gcc.

2) Write a c function that calls the function you want to call:

  #include <stdio.h>
   void somefunc (void)
   {
       int i = 0;

       printf("%d\n", i);
   }

3) compile with gcc -S. Note, if you don't like at&t syntax, you can use gcc -S masm=intel. Without that you end up with the at&t syntax, which is given below.

4) this outputs assembler code with the same name as your source file, with the extension .s, in this case, using 32 bit mingw:

    .file   "call_func.c"
    .section .rdata,"dr"
LC0:
    .ascii "%d\12\0"
    .text
    .globl  _somefunc
    .def    _somefunc;  .scl    2;  .type   32; .endef
_somefunc:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $40, %esp
    movl    $0, -12(%ebp)
    movl    -12(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    $LC0, (%esp)
    call    _printf
    leave
    ret
    .def    _printf;    .scl    2;  .type   32; .endef

5) look at what the compiler did, and do the same thing in your assembly code. In this case, the arguments to printf are pushed on the stack in right to left order, because it is using stdcall on Windows. Also note that c functions start with an underscore, this is typical.

6) get to the point where you don't want to do this anymore, and then look up the calling conventions for your platform, and then you will just know how to do it. Assuming you are on x86 or amd64, a reasonable place to start is the wikipedia page on x86 calling conventions.

Upvotes: 1

Related Questions