Article # 165, added by Geoworks, historical record
| first | previous | index | next | last |

How to call a C function from assembly.




Q. How do you call a C routine, from assembly?

A. Declare the routine name as "global" in assembly so the assembly
   compiler knows the routine is declared in another source file.
   Example:
	global	DRIVERINIT:far


   If the C function is defined as a standard routine (either the
   "_cdecl" flag or no routine type flag), then your push the
   parameters in reverse order, call the routine, then fix the
   stack pointer (SP).  For example:

   routine defined in C code as:
     word _cdecl foo(word a, word b)

   assembly code would do this:
     push b
     push a
     call _foo ; es, di, si, bx, cx trashed, ax holds return value
     add sp, 4 ; 4 is the two word-sized parameters, you could also
	       ; use the "pop" command twice.


   If the function is defined as pascal type, then you push the 
   parameters in order they are defined in the routine and call
   the routine name in all uppercase.  Example:

   routine defined in C code as:
     dword _pascal foo(word a, word b)

   assembly code:
     push a
     push b
     call FOO  ; es, di, si, bx, cx trashed, dx.ax holds return value
     ; don't need to fix up stack pointer because C routine does that


NOTE: if possible, you should define your C routines with the _pascal
pragma.  The pascal calling convention is smaller and faster than the
C calling convention.  


---------- Here's some sample code as an example ----------

**In the .def file:

; Define the following assembly and C routines as globally available.
    global    POWERONOFFCALLBACK:far
    global    CALLINTOC:far


**In the .goh file:

/* Declare globally available C routines. */
extern void
    _pascal PowerOnOffCallBack( word onOffValue );


**In the .asm file:

; Assembly function that will call C function.
callbackCode segment

CALLINTOC proc far
    uses ax
    .enter

    push ax
    call POWERONOFFCALLBACK

    .leave
    ret

CALLINTOC endp

callbackCode ends

; We don't know the segments for the C routines, so don't report errors.
.warn -unknown


**In the .goc file:

extern void _pascal
PowerOnOffCallBack( word onOffValue )
{
    ...
}