【发布时间】:2012-09-23 09:56:14
【问题描述】:
当我用 VC++10 编译这段代码时:
DWORD ran = rand();
return ran / 4096;
我得到了这个反汇编:
299: {
300: DWORD ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 shr eax,0Ch
302: }
00403949 ret
简洁明了,用逻辑右移代替了除以 2 的幂。
当我编译这段代码时:
int ran = rand();
return ran / 4096;
我得到了这个反汇编:
299: {
300: int ran = rand();
00403940 call dword ptr [__imp__rand (4050C0h)]
301: return ran / 4096;
00403946 cdq
00403947 and edx,0FFFh
0040394D add eax,edx
0040394F sar eax,0Ch
302: }
00403952 ret
在进行算术右移之前执行一些操作。
这些额外的操作需要什么?为什么算术移位还不够?
【问题讨论】:
-
FWIW,在 C89 和 C++03 中,它是由实现定义的,负操作数的整数除法循环方式。在 C99 和 C++11 中不是。
-
@Mysticial 我认为每个称职的 C(++)/低级程序员要么已经知道它,要么能够弄明白。或者赞成票来自那些还不知道这一点的人。我可能错了。
-
@Mysticial 好吧,我们也可以投票结束旧问题作为新问题的欺骗......
-
这是一个很好的例子,当你的意思是除法时人们说不要移位,因为编译器知道优化。结果编译器也知道什么时候“OK”。
标签: c++ visual-c++ assembly x86 division