14.3 工作原理
下面展示的是怎样用乘法来优化除法,其中借助了2^n的阶乘
M是一个magic系数
M的计算过程
因此这些代码片段通常具有这样的形式
n可以是任意数,可能是32(那么这样运算结果的高位部分从EX或者RDX寄存器中获取),可能是31(这种情况下乘法结果的高位部分结果右移)
n的选取是为了减少错误。
当进行有符号数除法运算,乘法结果的符号也会被放到输出结果中。
下面来看看不同之处。
int f3_32_signed(int a)
{
return a/3;
};
unsigned int f3_32_unsigned(unsigned int a)
{
return a/3;
};
在无符号版本的函数中,magic系数是0xAAAAAAAB,乘法结果被2^3*3除。
在有符号版本的函数中,magic系数是0x55555556,乘法结果被2^32除。
符号来自于乘法结果:高32位的结果右移31位(将符号位放在EAX中最不重要的位置)。如果最后结果为负,则会设置为1。
清单14.4:MSVC 2012/OX
_f3_32_unsigned PROC
mov eax, -1431655765 ; aaaaaaabH
mul DWORD PTR _a$[esp-4] ; unsigned multiply
shr edx, 1
mov eax, edx
ret 0
_f3_32_unsigned ENDP
_f3_32_signed PROC
mov eax, 1431655766 ; 55555556H
imul DWORD PTR _a$[esp-4] ; signed multiply
mov eax, edx
shr eax, 31 ; 0000001fH
add eax, edx ; add 1 if sign is negative
ret 0
_f3_32_signed ENDP
当前内容版权归 beginners.re 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 beginners.re .