我正在阅读《深入理解计算机系统》,而作业要求描述这个算法的工作原理。
C语言函数:
void store_prod(__int128 *dest, int64_t x, int64_t y) {
*dest = x * (__int128)y;
}
汇编语言:
movq %rdx, %rax
cqto
movq %rsi, %rcx
sarq $63, %rcx
imulq %rax, %rcx
imulq %rsi, %rdx
addq %rdx, %rcx
mulq %rsi
addq %rcx, %rdx
movq %rax, (%rdi)
movq %rdx, 8(%rdi)
ret
我不知道为什么它会表现出这种形式:xh * yl + yh * xl = value,这是我们在无符号乘法后添加的值
x
被提升为类型__int128
,因为在强制转换后y
是这种类型,而__int128
的整数提升等级高于int64_t
。其中一个转换由cqto
完成,但它只适用于rax
,因此另一个由sarq
转换。 - EOF1
或-1
进行乘法运算,应该使用0
或-1
。 算术右移与cqto
的作用相同:将符号扩展到整个寄存器(对于sarq
使用%rcx
,对于cqto
使用%rdx
)。 - EOFimul
已经提供了 64x64->128 位乘法,我认为这样做没有意义。当然你仍然可以解释它的工作原理 :) 这可能是禁用优化的常见情况,否则编译器足够聪明以使用单个imul
。 - Jester