views:

428

answers:

3

I am trying to build a windows console application without using the C runtime (msvcrt or libcmt). That is to link just against kernel32.lib and use console functions from WIN32 API instead of printf and such.

My problem is that during link the compiler fails to find __alldiv which seems to handle 64 bit integer divides in 32 bits applications. I tried both Microsoft's compiler and Intel's.

This function exist in the runtime libraries. It is quite annoying that something as basic as 64 bit integers will require the full C runtime.

Any ideas how to overcome the problem?

A: 

The msdn page for _alldiv says its use is dependent on compiler optimisation settings, without saying what the settings it depends on are.

There's also an _alldiv in Wine you might be able to borrow.

Pete Kirkham
+2  A: 

An extended precision division routine that can deal with a divisor larger than the hardware divider can handle is more complex than you might think. I once had to write a function to divide 128 values by 64 bit values, and it was rather painful (and slow in the general case).

Take a look at the algorithm that Randall Hyde discusses in his "Art of Assembly Language" text (Volume 4, Section 4.2.5 - Extended Precision Division).

Here's an excerpt:

You cannot synthesize a general n-bit/m-bit division operation using the DIV and IDIV instructions. Such an operation must be performed using a sequence of shift and subtract instructions and is extremely messy. However, a less general operation, dividing an n-bit quantity by a 32 bit quantity is easily synthesized using the DIV instruction. This section presents both methods for extended precision division.

Before describing how to perform a multi-precision division operation, you should note that some operations require an extended precision division even though they may look calculable with a single DIV or IDIV instruction. Dividing a 64-bit quantity by a 32-bit quantity is easy, as long as the resulting quotient fits into 32 bits. The DIV and IDIV instructions will handle this directly. However, if the quotient does not fit into 32 bits then you have to handle this problem as an extended precision division. The trick here is to divide the (zero or sign extended) H.O dword of the dividend by the divisor, and then repeat the process with the remainder and the L.O. dword of the dividend.

So, one thing you might want to do is determine if you really need to use 64-bit quantities in the divisor - if not, you can easily write up a function that will perform the task. If you really need to divide 64-bit values by 64-bit values, you can still do it, but it's a more difficult problem. More specifically it's probably not something that would be appropriate for a compiler to 'inline' - hence it's a library routine.

Oh, and don't forget - MS provides the library source code. __alldiv() is an assembly language function in lldiv.asm. It shouldn't be too hard to just add that file to your project and have it linked in without the remainder of the library.

Michael Burr
I feel I must disagree, not on the facts, but the opinion. I feel it is entirely appropriate to not couple the use of basic native types to the inclusion of the full runtime.
Chris Becke
+1  A: 

Found a solution for the __alldiv link problem:

Found lldiv.obj in msdev installation. I can add that object file to the link instead of the C runtime.

For me the path was:

c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\intel\mt_lib\lldiv.obj.

Gur