I have been writing 16-bit assembly applications for years and now need to be able to call some c code from my assembly code. A guy that has written the c code that I need is totally changing my assembly by changing my stack setup, data segment names, my near procs to far procs, changing my .obj link order,etc which has all resulted in various problems with my .asm programs which which won't work with all his changes to my .asm.
Is there an easier way to call a c function from 16-bit assembly without all these C overhead changes that I'm told have to be made to my .asm? Can I just include the c.obj in my link and call c function as a far call in my code, or is there much more involved in doing this as this c guy is telling me. code sample would be appreciated. I use Microsoft MASM v6.11, Link v5.60 for my assmbly & using Turbo-C version 2.01 for the new c stuff I'm trying to call from my .asm.
thanks in advance - Dale
I don't know what sort of programming style you use, but assuming that you take advantage of the MASM features intended to support mixed-language programming, and assuming that the C code uses standard memory models and calling conventions, calling C functions from your source should not be difficult. Here is a quick example that calls a few functions from the TC 2.01 libraries:
;====================================================================
.model large, c
.386
;====================================================================
printf PROTO c :VARARG
rand PROTO c
getch PROTO c
fact PROTO c :DWORD
;====================================================================
.stack
.data
fmtd db "%d%c",0
fmth db "%c%xh%c",0
.code
;====================================================================
;-------------------------------------------------------------
; This dummy procedure prevents the linker from returning an
; "unresolved external" error. Something in the library code
; is apparently referencing this name, and while the dummy
; procedure will satisfy the linker, if the library were to
; actually call the procedure it would probably fail.
;-------------------------------------------------------------
main proc
ret
main endp
.startup
;====================================================================
REPEAT 100
invoke rand
invoke printf, ADDR fmtd, ax, 9
ENDM
invoke printf, ADDR fmth, 10, 1234h, 10
invoke fact, 5
invoke printf, ADDR fmtd, ax, 10
invoke getch
;====================================================================
.exit
end
And the batch file that I use to build and run the test app:
ML /c clibtest.asm
pause
LINK16 /MAP clibtest.obj c0l.obj fact.obj,,,cl.lib;
pause
clibtest
pause
And a listing for the directory I was working in:
11/04/2008 03:49a 102 makeit.bat
11/04/2008 03:52a 1,327 clibtest.asm
05/11/1989 02:01a 2,043 C0L.OBJ
05/11/1989 02:01a 111,074 CL.LIB
01/13/1995 01:10p 364,544 LINK16.EXE
03/29/1999 05:45p 372,736 ML.EXE
07/22/2001 05:31a 9,687 ML.ERR
11/04/2008 03:52a 8,269 clibtest.map
11/04/2008 03:52a 12,188 clibtest.exe
11/04/2008 03:52a 3,628 clibtest.obj
11/04/2008 03:51a 439 FACT.OBJ
I used ML version 6.14 from the MASM32 package, but I think 6.11 should work the same for this.
I arbitrarily decided to use the Large memory model libraries. At least for the distribution that I have, there is a problem with the TC 2.01 libraries in that printf does not support floating-point formats. The only way I could find to correct this problem was to link in forcefp.obj from a later version of TC.
Edit:
After I installed TC 2.01 I changed the test to include a function created from this source (note that under Compiler/Options the Model must be set to large):
int fact( int n )
{
int res = 1;
printf( "n=%d\n", n );
while( n > 0 )
res *= n--;
return( res );
}
I have updated the ASM source, batch file, and directory listing to reflect the changes, and here is the generated output:
346 130 10982 1090 11656 7117 17595 6415 22948 31126
9004 14558 3571 22879 18492 1360 5412 26721 22463 25047
27119 31441 7190 13985 31214 27509 30252 26571 14779 19816
21681 19651 17995 23593 3734 13310 3979 21995 15561 16092
18489 11288 28466 8664 5892 13863 22766 5364 17639 21151
20427 100 25795 8812 15108 12666 12347 19042 19774 9169
5589 26383 9666 10941 13390 7878 13565 1779 16190 32233
53 13429 2285 2422 8333 31937 11636 13268 6460 6458
6936 8160 24842 29142 29667 24115 15116 17418 1156 4279
15008 15859 19561 8297 3755 22981 21275 29040 28690 1401
1234h
n=5
120