Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Calling asm from C

Thread Tools

Re: Calling asm from C

Posts: n/a
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];
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

Reply With Quote

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
define byte asm substitute? Edwin Knoppert ASP .Net 0 01-11-2006 02:06 PM
ASM (vs. BCEL) - can I do this? Francesco Devittori Java 2 12-21-2005 11:01 AM
ANN: 9Rays.Spices.Net [asm.browser, analyzer, obfuscator, decompiler, modeler]v3.4.2 released Al Ponomarev ASP .Net 3 05-03-2004 07:52 PM
OLD CISCO ASM CSC3 - Terminal line configuration Joe Bloggs Cisco 0 01-21-2004 02:02 PM
ASM Help toddneumiller Java 8 11-09-2003 08:24 AM