我注意到由编译器生成的x86汇编,有时会将无符号整数除法实现为整数乘法。这些优化似乎遵循以下形式:
value / n => (value * ((0xFFFFFFFF / n) + 1)) / 0x100000000
例如,进行9的除法:12345678 / 9 = (12345678 * 0x1C71C71D) / 0x100000000
除以 3 可以使用 0x55555555 + 1
进行乘法计算,其他数也同理。
由于 mul
指令会将结果的高位存储在 edx
寄存器中,因此可以通过一次乘法计算使用一个魔术数字得出最终的除法结果。(尽管有时候还需要在末尾进行位移。)
我想了解一下这是如何实现的。这种方法什么情况下适用?为什么必须加上 1 来使用我们的“魔数”?