Comments: Authenticated sender is From: "George Foot" To: Siddiqui Date: Thu, 27 Aug 1998 16:11:44 +0000 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: Adding precompiled code Reply-to: george DOT foot AT merton DOT oxford DOT ac DOT uk CC: djgpp AT delorie DOT com Message-Id: Precedence: bulk On 27 Aug 98 at 0:25, Siddiqui wrote: > If I wrote several assembly routines in a single file using somthng like > MASM,TASM or NASM :) how would I access these routines? Also how would I > pass variables to these routines (ie: change the values of the registers) There are two main ways to put assembly language routines into your C or C++ programs. You can either write them inline in the C or C++ source code or you can write separate pure assembly language files and link these in as if they were separate C or C++ files. The inline approach requires you to use AT&T syntax for your assembler. If you use external assembler modules you can use AT&T syntax (with the built in assembler, GAS) or Intel syntax (with NASM). For more information on inline assembly and the AT&T syntax please see Brennan's guide to inline assembler with djgpp: http://brennan.home.ml.org/djgpp/djgpp_asm.html and the relevant section of GCC's documentation: info gcc "c ext" "extended asm" For more information on external assembler routines using AT&T syntax please see the document I wrote about this: http://users.ox.ac.uk/~mert0407/asmfuncs.txt This does not describe the AT&T format in any detail; Brennan's guide (link above) is a good introduction to the AT&T format, and there is much more information in the documentation for GAS: info as machine i386 I can't give any links about NASM itself because I don't use it. To answer your question, referring to external assembler routines, you call them just like normal C functions. Write a prototype for the routine in a header file and include that header in any source that needs to call the function. Make sure the prototype is `extern "C"' if you're using C++. Also note that normally the C compiler adds an underline (`_') to the start of the function name to form its symbol name, so you must put this at the start of the label in the assembly language routine. Re: passing and returning values, there are calling conventions you must adhere to. These apply to external assembler routines; there are different rules for inline assembly (see Brennan's guide for information on that). Briefly, your external routines may clobber (change the value of) EAX, ECX, EDX, FS and GS; it must preserve all others. If it returns a non-floating point value it should leave it in EAX, or EAX:EDX if it's a 64-bit value. Floating point values are returned on the top of the FPU stack. Parameters to your function are pushed onto the CPU stack in reverse order, so the first parameter given is the last to be pushed. Note that the return address is pushed next, so your parameters will start at ESP+4 on entry (unless you're returning a struct, in which case the address of the struct is passed as an implicit 0th parameter -- so your regular parameters start at ESP+8). See the asmfuncs document above for much more information on this, and some examples. You shouldn't use registers to pass values between C functions and your assembly language functions. In theory you could but the C compiler might choose to destroy the value in the register before calling your function. If you're calling your assembler routines from other assembler routines then anything goes -- you can do pretty much whatever you want, so long as you put it all back before calling (or returning to) somebody else's code (i.e. gcc-compiled code or anything in libc). -- george DOT foot AT merton DOT oxford DOT ac DOT uk