News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

calling c functions from dos

Started by allynm, April 15, 2011, 02:05:16 AM

Previous topic - Next topic

dedndave

well - that is a strange workaround - lol
but it can be done that way

it doen't really accomplish what you are trying to do, though
which is to simply call functions in a 16-bit c library from an asm program

a much better soultion, after all, is to just write 32-bit code   :P

jj2007

Quote from: allynm on April 17, 2011, 10:35:17 PMJJ's workaround seems to load and unload 32 bit Windows API's from a DOS .exe.

Mark,
Yes, it does use 32 bit Windows - from a 120 byte COM program! I attach a complete example, which works fine on Win XP SP2, adapted from Arkon's code.

And I agree with DednDave - write 32-bit code, it's much easier :bg

dedndave

the way those examples are written, i see no advantage in using that method
again, you may as well write a 32-bit program
the same thing could be accomplished by using the INT 21h Exec function to execute a 32-bit program   :P
and, what is the advantage in that, anyways ? - lol

allynm

Hello Dedndave, MichaelW, and JJ,

OK.  So, I got a copy of Borland 2.01 (thanks to Dave), and wrote a small program that pretty much duplicates what MichaleW sent early on in this thread.  I just simplified slightly what MichaelW created.

Here it is.


; BOR201.asm
.model large, c
.386

includelib c:\tc\lib\cl.lib

printf PROTO C :VARARG
.stack
.data

fmt1 db  "%d", 0
val word 23

.code

main PROC
ret
main ENDP


.startup
invoke printf, ADDR fmt1, val
ret
.exit
END

If I assemble the code with ml /c /omf bor201.asm it assembles.  If I link with ..\bin\link16 /map c:\TC\lib\c0l.obj bor201.obj, bor201.exe  the link fails with an error message stating that I have too many segments.  I haven't seen this message before, and I don't know how to interpret it or fix the problem.

Any suggestions, folks?

Regards,
Mark

allynm

JJ and Dedndave,

This is a separate response to your posts regarding JJ's workaround.  I agree with both of you that the easiest thing to do is simply write the whole thing in 32 bit form and get on with life.  No question about it.

If you don't mind just a bit of personal information to help clarify:  I come very late in life to computer programming, especially with microsoft.  Many years ago I played around programming MACs in ThinkC, but was interrupted by other life events.  I've retired recently and have the time to go back and learn stuff you folks learned long ago---such as, for example, DOS and assembly language.  So....  when JJ posted what he posted his contribution was really exceptionally educational and I was fascinated by the ingenuity of the code.  Its really great to be able to participate on a site like this where you folks are so willing to share what you have learned by dint of great effort over a long time.  Believe me, whatever you post I read carefully and I learn.

Thanks for your patience

Mark Allyn

dedndave

attach the 2 OBJ files   :U
you can peek inside them with a binary editor to see how the segments are named and ordered
for MZ EXE's, the segment names disappear once it has been converted to an EXE
also - you may want to browse the compiler documentation
it should tell you how the segments are created

oh - and....
make sure you use the memory model in the asm file that matches the lib
again - i would start with SMALL !!!
once you get that working, you can try medium or large

dedndave

if you can write a C program and compile it.....
use a simple C function, like output a single char - not printf
use SMALL model
attach the resulting exe

jj2007

Quote from: allynm on April 18, 2011, 05:02:01 PMSo....  when JJ posted what he posted his contribution was really exceptionally educational and I was fascinated by the ingenuity of the code.

Mark,

I would feel really flattered if it was my code :bg

... but I am afraid credits must go to Gil Dabah aka Arkon

MichaelW

QuoteIf I link with ..\bin\link16 /map c:\TC\lib\c0l.obj bor201.obj, bor201.exe  the link fails

The object module that contains the program entry point needs to be the first one listed, so the order needs to be:

bor201.obj c0l.obj

BTW, for the Watcom library I seem to have the simple stuff working. But so far I have not found any way to enable floating-point support, I cannot get the memory allocation functions to work, and my qsort test hangs. I'll post what I have working later.



eschew obfuscation

dedndave

Michael,
have a look at the docs (i posted a link above)
there are certain function groups that require initialization
i am sure f.p. is one of them

Mark,
if you do compile the simple program i mentioned above, please include the OBJ, as well as the EXE, if possible

allynm

DednDave and MichaelW,

I know I haven't kept up with Dave's suggestions, for which I apologize. I read MichaelW's post and realized where I had gone wrong on the command line, and I made the changes on the link16 order in which files were linked.  And the good news is that the program did "successfully" link in the sense that no errors were generated.  Moreover, when called, the program does not generate runtime errors either.  HOWEVER, it also doesn't output the simple string that I give for printf to print.  It skips a line and comes back with a dos prompt.


;bor201.asm
.model large, c
.386


printf PROTO C :VARARG
.stack
.data


fmt2 db "%s", 0
msg db  "Hiya, you persistent fool", 0


.code

main PROC
ret
main ENDP


.startup
invoke printf, ADDR fmt2, ADDR msg
ret
.exit

END


I'm probably missing something obvious here, and will ultimately feel stupid, but I can't see what it is.  DednDave, I apologize for not pursuing your suggestions yet, but I really thought that we had finally nailed this thing by getting the link16 command properly called.

Also, I looked at Borland 5.0 and it does have the necessary DOS library in it.  I have however been using Borland 2.01 for this work.

Regards,
Mark

allynm

Hi DednDave, MichaelW, and JJ--

Well, I found my own bug and it was as I thought it would be staring me right in the face.  It was the ret instruction at the end of the code.  I just threw it in by habit and it caused the woes...

Here is the code now:



.model large, c
.386


printf PROTO C :VARARG
fputchar PROTO C :WORD

.stack
.data


fmt2 db  "%s", 0
msg db  "Hiya, you persistent fool", 0


.code

main PROC
ret
main ENDP


.startup
invoke printf, ADDR fmt2, ADDR msg
xor ax, ax
mov ax, 'k'
invoke fputchar, ax

.exit

END



For what its worth, I threw in a call to putchar and discovered that in the cl.lib for Borland, putchar doesn't exist.  But, fputchar does, and it works just like putchar.  Wonder why they wandered off the ANSI ranch...

Regards to all of you and thanks for your very helpful and informative input.
I am going to follow up on DednDave's suggestions .

Regards, Mark

allynm

Hi MichaelW,

I haven't caught up yet with your work on Watcom.  I will do that shortly.  Thanks for continuing to work on this problem. 

Mark

MichaelW

#43
I finally overcame all but one of the problems, namely the "Floating-point support not loaded" error when I attempt to display a floating-point value with one of the printf functions. It turns out that normally the Watcom linker links in this support when it detects a reference to a fltused_ symbol that the compiler places in any module that requires floating-point support. After spending hours trying to find a procedure that would provide this support, I decided that I had already spent far too much time on this detail, considering that the missing support apparently affects only the display of a floating-point value with one of the printf functions, and gave up on it. As a workaround, that is included in the test, you can simply convert the value to a string and then display it as such. The Watcom libraries that I used were:

WATCOM\LIB286\NOEMU87.LIB
WATCOM\LIB286\MATH87S.LIB
WATCOM\LIB286\DOS\CLIBS.LIB
eschew obfuscation