Re: Calling asm from C

Discussion in 'C Programming' started by santosh, Mar 8, 2008.

  1. santosh

    santosh Guest

    Frank Kotler wrote:

    > Since this newsgroup is *determined* to talk about C recently, the
    > *least* we can do is call some asm from it!
    >
    > Us "purists" don't like it much, but in the real world, most asm is in
    > subroutines called from C[++]. The hard parts are done in asm, and
    > C[++] provides the "glue" that holds it together, and provides the
    > OS-specific parts. (not going to be portable across CPUs, of course)
    >
    > An alternative to this would be inline asm. When the C folks talk
    > about portability, they ain't talking about cross-toolchain
    > portability of inline asm!!! Awful mess. Maybe gcc on Linux (BSD/Mac)
    > vs gcc on Windows would work...
    >
    > An object file of the proper format will (should) link with object
    > file(s) of the same format, regardless of *what* language the were
    > written in ("Python" is popular... I wanna wrestle a carniverous
    > reptile that outweighs me... Yeah, right!). Different kind of
    > "portability".
    >
    > Since Nasm will produce object files in a variety of formats, it's a
    > suitable tool for the asm part. We won't have "binary portability" of
    > course, it'll have to be re-assembled for each OS we want to use it
    > with (same as C)...
    >
    > I don't suppose C has a "getcpuvendor()"... maybe it does. Struck me
    > as something this might be "good for". (a better example might pass
    > more parameters...) Something like:
    >
    > bits 32
    > global getvendor
    >
    > section .text
    > getvendor:
    > pusha
    > xor eax, eax
    > cpuid
    > mov eax, [esp + 36]
    > mov [eax], ebx
    > mov [eax + 4], edx
    > mov [eax + 8], ecx
    > mov byte [eax + 12], 0
    > popa
    > xor eax, eax
    > ret
    >
    > For Linux, we can assemble this as "nasm -f elf getvendor.asm" - add
    > "-g" or "-O" switches if you want... For other-than-ELF, we probably
    > want an underscore on "getvendor", so "nasm -f win32 --prefix _
    > getvendor.asm". I'm not sure if MacIntel wants underscores for "-f
    > macho" or not. If my information is correct, Watcom C wants a
    > *trailing* underscore... "--postfix _" should do it. Hmmmm, what
    > output format would Watcom want? Hmmm... Borland wants "-f obj", I
    > believe. "-f obj" defaults to "bits 16", so we'll need "bits 32" if we
    > want it to work with "-f obj" - won't hurt "-f elf", etc... There, I
    > put it in (improving already!).
    >
    > Now, we'll want something to call it from...
    >
    > main()
    > {char vendorbuf[13];
    > getvendor(vendorbuf);
    >
    > puts(vendorbuf);
    > }
    >
    > gcc -o getvendortest getvendortest.c getvendor.o
    >
    > That's horribly improper C. Won't tolerate "-Wall". We'll want "int
    > main"... "puts" is implicitly declared in "stdio.h", I guess. We could
    > include a "getvendor.h"... hardly seems worthwhile. "Prototype" it
    > here? (before or after "main"...?) An explict "return". What's the
    > "minimal" but "correct" way to do it?


    This might be better:

    #include <stdio.h>

    void getvendor(char *vendorbuf);

    int main(void) {
    char vendorbuf[13];
    getvendor(vendorbuf);
    puts(vendorbuf);
    return 0;
    }

    This assumes that vendorbuf is big enough for getvendor and that
    getvendor terminates it's output with a null character. Otherwise bad
    things are likely to happen.

    The real issue is the ABI. The ABI that the C compiler decides on *must*
    agree with the ABI that the assembler routine expects. There is
    unlikely to be much of a problem for a simple example like this, but
    there are more headaches when it comes to complex routines that accept
    many types of parameters, especially structures and also return complex
    types like structures or unions. The only way to make the assembler and
    the C code interoperate is to learn the ABI for that C implementation
    and adjust the assembler code accordingly. It *is* possible to tell the
    C compiler to use a different ABI, but this is likely to be a more
    slippery path, as not all compilers have such support, and it isn't as
    flexible as modifying your assembler code.

    Take this example C function

    struct ret_struct my_func(
    ptrdiff_t p,
    size_t s,
    struct example ex,
    unsigned long long ull,
    void (*fx)(int *, int *),
    char c
    );

    This is artificial, but it does illustrate that this is not a simple
    matter. You need to know the exact sizes of the above parameters and
    how they should be laid out on the stack for the C compiler to not
    choke on it. A similar complicated assembler routine must also know how
    the C compiler would send it it's arguments and where it would expect
    the return value.

    There is no portable (from C's POV) way to do this.

    > I don't know how to call it from VB or whateverall... any gurus? Hey,
    > we can call it from asm!
    >
    > global _start
    > extern getvendor
    >
    > section .text
    > _start:
    > nop
    > commence:
    > push vendorbuf
    > call getvendor
    > add esp, 4
    >
    > mov ecx, vendorbuf
    > mov edx, 12
    > call write_stdout
    >
    > mov ebx, eax
    > mov eax, 1
    > int 80h
    >
    > ;------------------
    > write_stdout:
    > mov ebx, 1 ; STDOUT
    > mov eax, 4 ; __NR_write
    > int 80h
    > ret
    > ;-------------------
    >
    > section .bss
    > vendorbuf resb 13
    > ;-----------------------
    >
    > That'll have to be changed for other-than-Linux, of course.
    > WriteFile... put it in a window with some fancy font, if you like...
    > Maybe, for Windows, we ought to arrange for "ret 4" in the callee so
    > it'd be more like an API call?
    >
    > Just a first draft...
    >
    > Best,
    > Frank
     
    santosh, Mar 8, 2008
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Al Ponomarev
    Replies:
    3
    Views:
    469
    Ken Cox [Microsoft MVP]
    May 3, 2004
  2. Edwin Knoppert

    define byte asm substitute?

    Edwin Knoppert, Jan 11, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    507
    Edwin Knoppert
    Jan 11, 2006
  3. toddneumiller

    ASM Help

    toddneumiller, Nov 6, 2003, in forum: Java
    Replies:
    8
    Views:
    535
  4. Francesco Devittori

    ASM (vs. BCEL) - can I do this?

    Francesco Devittori, Dec 20, 2005, in forum: Java
    Replies:
    2
    Views:
    1,341
    Francesco Devittori
    Dec 21, 2005
  5. Oliver Batchelor
    Replies:
    1
    Views:
    377
    Frank Schmitt
    Jul 22, 2003
Loading...

Share This Page