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 ) { ... }