2

C ランタイム (msvcrt または libcmt) を使用せずに Windows コンソール アプリケーションをビルドしようとしています。つまり、kernel32.lib に対してのみリンクし、printf などの代わりに WIN32 API のコンソール関数を使用します。

私の問題は、リンク中にコンパイラが __alldiv を見つけられないことです。これは、32 ビット アプリケーションで 64 ビット整数除算を処理しているようです。Microsoft のコンパイラと Intel のコンパイラの両方を試しました。

この関数はランタイム ライブラリに存在します。64 ビット整数のような基本的なものに完全な C ランタイムが必要になるのは非常に面倒です。

問題を克服する方法はありますか?

4

3 に答える 3

2

ハードウェア除算器が処理できるよりも大きな除数を処理できる拡張精度除算ルーチンは、想像以上に複雑です。以前、128 個の値を 64 ビット値で除算する関数を書かなければならなかったことがありますが、かなり面倒でした (そして、一般的に遅い)。

Randall Hyde が彼の「Art of Assembly Language」テキスト (Volume 4、Section 4.2.5 - Extended Precision Division) で説明しているアルゴリズムを見てください。

ここに抜粋があります:

DIV 命令および IDIV 命令を使用して、一般的な n ビット / m ビットの除算演算を合成することはできません。このような演算は、一連のシフト命令と減算命令を使用して実行する必要があり、非常に面倒です。ただし、n ビット量を 32 ビット量で除算する一般的ではない操作は、DIV 命令を使用して簡単に合成できます。このセクションでは、拡張精度除算の両方の方法を示します。

多倍精度除算演算の実行方法を説明する前に、一部の演算では、単一の DIV または IDIV 命令で計算できるように見えても、拡張精度除算が必要になることに注意してください。結果の商が 32 ビットに収まる限り、64 ビット量を 32 ビット量で割るのは簡単です。DIV および IDIV 命令は、これを直接処理します。ただし、商が 32 ビットに収まらない場合は、この問題を拡張精度除算として処理する必要があります。ここでの秘訣は、被除数の (ゼロまたは符号拡張された) HO dword を除数で割り、剰余と被除数の LO dword を使用してプロセスを繰り返すことです。

したがって、除数に 64 ビットの量を本当に使用する必要があるかどうかを判断することをお勧めします。そうでない場合は、そのタスクを実行する関数を簡単に作成できます。64 ビット値を 64 ビット値で本当に除算する必要がある場合でも、それを行うことができますが、それはより難しい問題です。より具体的には、おそらくコンパイラが「インライン化」するのに適したものではないため、ライブラリルーチンです。

ああ、忘れないでください - MS はライブラリのソース コードを提供しています。 __alldiv()のアセンブリ言語関数ですlldiv.asm。そのファイルをプロジェクトに追加するだけで、残りのライブラリなしでリンクするのはそれほど難しくありません。

于 2009-01-27T08:58:18.600 に答える
2

__alldiv リンクの問題の解決策を見つけました:

msdev インストールでlldiv.objが見つかりました。C ランタイムの代わりに、そのオブジェクト ファイルをリンクに追加できます。

私にとってのパスは次のとおりです。

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

于 2009-01-27T09:17:24.287 に答える
0

_alldivのmsdnページには、その使用はコンパイラの最適化設定に依存していると書かれていますが、依存する設定が何であるかについては言及されていません。

借りることができるかもしれない Wine の _alldiv もあります。

于 2009-01-27T08:36:58.843 に答える