在vc release模式下调试时,经常可以看到下面形式的汇编代码:
00FB1202 mov ecx,dword ptr ds:[00FB543Ch]
00FB1208 sub ecx,dword ptr ds:[00FB5438h]
00FB120E mov eax,66666667h
00FB1213 imul ecx
00FB1215 sar edx,5
00FB1218 mov ecx,edx
00FB121A shr ecx,1Fh
00FB121D add ecx,edx
其实这是当被除数是常量时除法的编译器优化。x
/50h
优化方法是把除法转换成乘以被除数然后右移.
x/y => x*(1 /y) => x* ((1<<37) /((1<<37)* y) ) =>x * ((1<<37)/ y)>>37
为了取整效果,最终结果将会是x/y = x * ((1<<37 +y-1 )/ y)>>37由于y 是常量,在编译期,编译器就可以计算出((1<<37 +y-1 )/ y)的值。
那么实际计算时,编译期就可以把 x/y 转换成 x *M >> 37, M = ((1<<37 +y-1 )/ y)
除以0x50 M = (1<<37 + 0x4F)/0x50 = 0x66666667
那么x / 0x50相当于 (x* 0x66666667)>>37