在没有 C 运行时的情况下使用 64 位整数 - 链接错误 __alldiv

发布于 2024-07-12 23:08:18 字数 298 浏览 7 评论 0原文

我正在尝试在不使用 C 运行时(msvcrt 或 libcmt)的情况下构建 Windows 控制台应用程序。 也就是说,仅链接 kernel32.lib 并使用 WIN32 API 中的控制台函数而不是 printf 等。

我的问题是,在链接期间,编译器无法找到 __alldiv,它似乎可以处理 32 位应用程序中的 64 位整数除法。 我尝试了微软的编译器和英特尔的编译器。

该函数存在于运行时库中。 令人烦恼的是,像 64 位整数这样的基本数据将需要完整的 C 运行时。

有什么想法如何克服这个问题吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我最亲爱的 2024-07-19 23:08:19

扩展精度除法例程可以处理比硬件除法器可以处理的除数更大的除数,这比您想象的要复杂。 我曾经不得不编写一个函数来将 128 位值除以 64 位值,这是相当痛苦的(并且在一般情况下很慢)。

看看 Randall Hyde 在他的 《Art of Assembly》中讨论的算法语言”文本(第 4 卷,第 4.2.5 节 - 扩展精度除法)

这是摘录:

您无法使用 DIV 和 IDIV 指令合成一般的 n 位/m 位除法运算。 这样的操作必须使用一系列移位和减法指令来执行,并且非常混乱。 然而,使用 DIV 指令可以轻松合成一个不太通用的操作,即将 n 位数量除以 32 位数量。 本节介绍两种扩展精度除法的方法。

在描述如何执行多精度除法运算之前,您应该注意,某些运算需要扩展精度除法,即使它们看起来可以使用单个 DIV 或 IDIV 指令进行计算。 将 64 位数量除以 32 位数量很容易,只要所得商适合 32 位即可。 DIV 和 IDIV 指令将直接处理此问题。 但是,如果商不能容纳 32 位,那么您必须将这个问题作为扩展精度除法来处理。 这里的技巧是将被除数的(零或符号扩展)HO 双字除以除数,然后用余数和被除数的 LO 双字重复该过程。

因此,您可能想做的一件事是确定是否确实需要在除数中使用 64 位数量 - 如果不需要,您可以轻松编写一个执行该任务的函数。 如果您确实需要将 64 位值除以 64 位值,您仍然可以这样做,但这是一个更困难的问题。 更具体地说,它可能不适合编译器“内联” - 因此它是一个库例程。

哦,不要忘记 - MS 提供了库源代码。 __alldiv()lldiv.asm 中的汇编语言函数。 将该文件添加到您的项目中并在没有库的其余部分的情况下链接它应该不会太难。

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.

﹏半生如梦愿梦如真 2024-07-19 23:08:19

找到了__alldiv链接问题的解决方案:

在msdev安装中找到lldiv.obj
我可以将该目标文件而不是 C 运行时添加到链接中。

对我来说,路径是:

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

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.

Oo萌小芽oO 2024-07-19 23:08:19

_alldiv 的 msdn 页面表示其用途是依赖于编译器优化设置,而不说明它依赖的设置是什么。

Wine 中还有一个 _alldiv 您可以借用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文