Previous Next Contents

5. CALLING CONVENTIONS

5.1 Linux

Linking to GCC

That's the preferred way.

32-bit arguments are pushed down stack in reverse order (hence accessed/popped in the right order) above the 32-bit near return address. %ebp, %esi, %edi, %ebx are preserved, %eax holds the result, or %edx:%eax for 64-bit results.

FP stack: I'm not sure, but I think it's result in st(0), whole stack callee-save.

Note that GCC has options to modify the calling conventions by reserving registers, having arguments in registers, not assuming the FPU, etc. Check the i386 info pages.

Beware that you must then declare the cdecl attribute for a function that will follow standard GCC calling conventions (I don't know what it does with modified calling conventions). See in the GCC info pages the section: C Extensions::Extended Asm::

ELF vs a.out problems

Some C compilers prepend an underscore before every symbol, while others do not.

Particularly, Linux a.out GCC does such prepending, while Linux ELF GCC does not.

If you need cope with both behaviors at once, see how existing packages do. For instance, get an old Linux source tree, the Elk, qthreads, or OCAML...

You can also override the implicit C->asm renaming by inserting statements like


        void foo asm("bar") (void);

to be sure that the C function foo will be called really bar in assembly.

Note that the utility objcopy, from the binutils package, should allow you to transform your a.out objects into ELF objects, and perhaps the contrary too, in some cases. More generally, it will do lots of file format conversions.

Direct Linux syscalls

This is specifically NOT recommended, because it may change, it's not portable, it's a burden to write, it's redundant with the libc effort, AND it precludes fixes and extensions that are made to the libc, like, for instance the zlibc package, that does on-the-fly transparent decompression of gzip-compressed files. The standard, recommended way to call Linux system services is, and will stay, to go through the libc.

Shared objects should keep your stuff small. And if you really want smaller binaries, do use #! stuff, with the interpreter having all the overhead you want to keep out of your binaries.

Now, if for some reason, you don't want to link to the libc, go get the libc and understand how it works! After all, you're pretending to replace it, ain't you? You might see how linux-eforth-1.0c.tgz does it ftp://ftp.forth.org/pub/Forth/Linux/ The sources for Linux come in handy, too, particularly the asm/unistd.h header file, that describes how to do system calls...

Basically, you issue an int $0x80, with the __NR_syscallname number (from asm/unistd.h) in %eax, and parameters (up to five) in %ebx, %ecx, %edx, %esi, %edi respectively. Result is returned in %eax, with a negative result being an error whose opposite is what libc would put in errno. The user-stack is not touched, so you needn't have a valid one when doing a syscall.

I/O under Linux

If you want to do direct I/O under Linux, either it's something very simple that needn't OS arbitration, and you should see the IO-Port-Programming mini-HOWTO; or it needs a kernel device driver, and you should try to learn more about kernel hacking, device driver development, kernel modules, etc, for which there are other excellent HOWTOs and documents from the LDP.

Particularly, if what you want is Graphics programming, then do join the GGI project: http://synergy.caltech.edu/~ggi/ http://sunserver1.rz.uni-duesseldorf.de/~becka/doc/scrdrv.html

Anyway, in all these cases, you'll be better off using GCC inline assembly with the macros from linux/asm/*.h than writing full assembly source files.

5.2 DOS

Most DOS extenders come with some interface to DOS services. Read their docs about that, but often, they just simulate int $0x21 and such, so you do ``as if'' you were in real mode (I doubt they have stubs to have things work with 32-bit operands by calling 16-bit DOS services as needed).

Docs about DPMI and such (and much more) can be found on ftp://x2ftp.oulu.fi/pub/msdos/programming/

DJGPP comes with its own (limited) glibc derivative/subset/replacement, too.

It is possible to cross-compile from Linux to DOS, see the devel/msdos/ directory of your local FTP mirror for sunsite.unc.edu Also see the MOSS dos-extender from the Flux project in utah.

Other documents and FAQs are more DOS-centered. We do not recommend DOS development.

5.3 Winblows and suches

Hey, this document covers only free software. Ring me when Winblows becomes free, or when there are free dev tools for it!

Well, there might be after all; I've heard about cygwin32 from Cygnus support.

5.4 Yer very own OS

That's what many asm programmers talk about

Boot loader code & getting into 32-bit mode

The basics about protection

Handling Interrupts

V86/R86 mode for using 16-bit system services.

Defining your object format and calling conventions

Where to find info about it all.

Please add pointers to other documents to this section

The main source for information is sources of existing OSes. Lots of pointers lie in the following WWW page: http://www.eleves.ens.fr:8080/home/rideau/Tunes/Review/OSes.html

Particularly interesting are Cygnus support's ftp.cygnus.com archive (or a mirror like ftp://sunsite.doc.ic.ac.uk/packages/gnu/cygnus/), and the Flux project ( http://ww.cs.utah.edu/projects/flux/).


Previous Next Contents