看看编译器是怎样用乘法代替除法的

来源:互联网 发布:stm32定时器计算软件 编辑:程序博客网 时间:2024/04/27 19:31

在0与1的计算机世界中,最复杂的运算就是除法了。复杂到什么程度呢?就是不到万不得已的情况下,连编译器自己都不愿意产生除法指令。

备注:以下分析,主要针对的情况为 除数不是2的指数。如果除法是2的指数,尽可以简单地使用移位来运算。比如, 20 / 4 = 20 >> 2 = 5(2 ^ '2' = 4)。

1.例程代码

简单的C程序:

Linux下通过 gcc -S div5.c 产生的汇编代码div5.s

2.代码分析

通过代码分析,这里将除法转换为乘法的方法就是

x = y / divider = (y * M) >> 33;  其中M = ((1 << 33) + 3)  / divider,当divider=5, M=1717986919=0x66666667

推导证明过程,我没有深入研究,在此也不作赘述。

汇编代码部分,我就乘法指令“IMUL source”,作简单说明。

source为乘数,在使用IMUL指令之前,需将被乘数置于EAX寄存器中,如果结果为64位值(如两个4字节数之间的乘法),最终的结果放置在EDX:EAX寄存器对中,高32位值在EDX中,低32位值在EAX中。将(y * divider)的结果右移33位,其实就是将EDX右移1位。

0 0