汇编指令中乘法的低位部分和高位部分分别是什么

1 c++ assembly

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

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

为了澄清起见,我正在研究汇编的好处,当时我遇到人们在多篇文章中说,当前的编译器在 64 位乘法方面没有进行优化,因为它们使用最低部分,所以它们不执行完整的 64 位乘法什么是不是这个意思。那么,获得较高部分的含义是什么?我在一本书中读到,在 64 位架构中,只有最低 32 位用于 RFlags,这些相关吗?我很困惑吗?

Jer*_*fin 5

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

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

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

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

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

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