组装指令中乘法的下部和上部是什么

What is the Lower and the higher part of multiplication in assembly instructions

本文关键字:下部 是什么 指令      更新时间:2023-10-16

我正在阅读此链接,简而言之,有人可以向一周前开始学习汇编x86和64bit的人解释当前C++编译器的问题。

不幸的是,当前的编译器没有优化@craigster0很好 便携式版本,因此,如果您想利用 64 位 CPU,您可以 不能使用它,除非作为您没有 #ifdef 的目标的后备 为。(我没有看到优化它的通用方法;你需要一个 128 位 类型或内部函数。

为了澄清起见,当我遇到有人在多篇帖子中说当前的编译器在 64 位乘法方面没有优化时,我正在研究组装的好处,因为它们使用最低部分,因此他们不执行完整的 64 位乘法这意味着什么。 那么获得更高部分的含义是什么 我也在一本书中读到,我在 64位架构 只有最低的 32 位用于 RFlags,这些相关我感到困惑吗?

大多数 CPU 允许您从两个操作数开始,每个操作数的大小相当于一个寄存器的大小,然后将它们相乘以获得填充两个寄存器的结果。

例如,在x86 上,如果将两个 32 位数字相乘,则在 EDX 中将获得结果的前 32 位,在 EAX 中获得结果的低 32 位。如果将两个 64 位数字相乘,则会得到 RDX 和 RAX 的结果。

在其他处理器上,使用其他寄存器,但相同的基本思想适用:一个寄存器乘以一个寄存器给出填充两个寄存器的结果。

C 和 C++ 没有提供利用该功能的简单方法。当你对小于int的类型进行操作时,输入操作数将转换为int,然后整数相乘,结果为 int。如果输入大于 int,则它们将乘以相同的类型,结果是相同的类型。没有采取任何措施来考虑结果是输入类型的两倍,并且实际上地球上的每个处理器都会产生比每个输入单独两倍的结果。

当然,有办法解决这个问题。最简单的是我们在小学学到的基本因式分解:将每个数字分解为上半部分和下半部分。然后我们可以将这些片段单独相乘:(a+b( * (c+d( = ac + ad + bc + bd。由于这些乘法中的每一个只有一半的非零位,我们可以将每段算术作为半大小运算来产生一个全大小的结果(加上从加法中执行的单个位(。例如,如果我们想在 64 位处理器上进行 64 位乘法以获得 128 位结果,我们会将每个 64 位输入分成 32 位部分。然后每次乘法都会产生一个 64 位的结果。然后,我们将各个片段(具有合适的位移(相加,以获得最终的 128 位结果。

但是,正如彼得所指出的,当我们这样做时,编译器不够聪明,无法意识到我们想要完成什么,并将乘法和加法序列重新转换为单个乘法,产生的结果是每个输入的两倍。相反,它将表达式相当直接地转换为一系列乘法和加法,因此它花费的时间大约是单次乘法的四倍。