My saga continues.

I wanted to see if I could make a static library in vc++, which itself calls out to the standard c library, and then use that library's functions from an assembly program.

So I made the library. First off I made it to just call MessageBox, knowing that throwing the std c library into the mix would mess everything up. It was no problem and worked correctly. Then I added a call to printf (from inside my library). I put a MessageBox call in that function to just to be sure to see what was going on.

Here comes the fun.

Creating a client program to this library in vc++ worked correctly. I see the message box and I see the printf output.

However an assembly language program, linked to the same library, produces the MessageBox, but no printf output!!

How is this even possible?

I turned on /verbose for the linker in both vc++ and for the masm program, and both outputs seemed very similar, bringing in the same libc.lib and other libraries in a very similar manner. No glaring differences, in any case.

After looking at this for many hours, my only thought was this. Based on an old Knowledge Base article from the msdn, (#Q86816), a special instruction needs to be added in order to "force a load of the C startup code", which was:

EXTRN _acrtused:abs

Unfortunately this symbol "_acrtused" is no longer around, and this knowledge base article seems to be out of date.

I don't know if vc++ is doing some special magic in order to get the "C startup code" going. I don't even know what "C startup code" means!! Maybe it's just the stupid stuff related to getting argv, argc and calling main(). It's not explained any further in msdn, as far as I can tell.

Well, I'll attach some files in case any one else is as masochistic as I am apparently being right now, and wants to see this mess first hand.

Thanks.
Posted on 2001-12-14 12:05:32 by cmonahan
two vc++ projects, library and client and one masm project (assembly language client to vc++ lib), Makefile and all.
Posted on 2001-12-14 12:07:27 by cmonahan
It's possible that the whole library issue is just complicating matters to some extent.

Obviously libc.lib is needed, but I can get the no-output printf behavior from my assembly language program in a more straightforward manner, I found.

1. Use h2inc to get an include file from stdio.h
2. include that file
3. call printf in asm file
4. Give link a /LIBDIR option pointing to vc++ lib dir

No output.

Once again, my only hunch is that some setup code from libc or perhaps elsewhere needs to be executed in order to get some environment set up for printf. Just a guess, and I can't seem to find anything to support the guess, except the old 16 bit _acrtused thing.
Posted on 2001-12-14 13:27:56 by cmonahan
since printf "uses" the buffered io system, it is nessessary to execute initialization code. In VC, I think this is function _ioinit(). This should be called before any call to printf.

To be sure all C runtime functions you want to call from your asm prog are properly initialized it is a better idea to make a small C stub program just with function main() and call your ASM "main" function from inside this function.

japheth
Posted on 2001-12-14 13:57:21 by japheth
Well, yes for 2000, no for WinME. I don't know what vc++ is doing to get printf going on ME, but it does, and this must not be the extent of it.

In other news, the floating point system has me equally perplexed, that is, I can get printf working (on 2k), but then something like
printf("%f\n",3.14);
outputs 0.000000.

Apparently (looking at libc source code), there's an array of 6 functions for doing floating point translation that gets initialized *somewhere,* perhaps partially in _cinit, but apparently that's not all of it. _fpmath makes it sort of halfway work, I think that gives the 0.000000 instead of ending up bombing out, and then another function FPinit which takes some parameters I can't deduce (I think, because calling it without any crashes the program)...

In anycase I wouldn't have thought to look in all those crannies without knowing the new search keyword "_ioinit". Thanks!! :)
Posted on 2001-12-17 11:26:10 by cmonahan
As it turns out the 0.000000 float conversion problem I was having was resolved by using REAL8 instead of REAL4. I'm not sure why I was unable to use REAL4, but it is working now.
Posted on 2001-12-19 09:58:14 by cmonahan