c++
printf("nVarone / 8 = %d", nVarone / 8);
汇编代码
mov eax,dword ptr[ebp-4]]
cdq
and edx,7 //edx为高位
add eax.edx //eax+(2^n-1),n=3
sar eax,3
push...
call...(printf函数调用)
其中cdq作用是将符号位扩展到高位。
例如将为负数的-1扩展到高位:1111 1111 -> 1111 1111 1111 1111
而正数高位则以0覆盖:0000 0001 -> 0000 0000 0000 0001
这是因为历史原因要求 被除数的位数需要是除数的两倍 因此需要扩展符号位
关于除法(除数为2的幂)
如果为负数,则其补码需要加上 2^n-1 后在进行移位
因为计算机是进行除法运算时,是没有余数的,是对商进行取整的(靠0取整)
正数为向下取整
9/8 =1
而负数则为向上取整
-9/8=-1
计算机中移位则可以看作为向下取整
0000 1001 >> 3 = 0000 0001 // 1
1111 0111 >> 3 = 1111 1110 // -2 而我们想要的是-1
因此在进行除法运算时,正数可以直接移位就行,而负数不行,需要经行转换
公式 当b>0时: ⌈a / b⌉ =⌊(a+b-1) / b⌋ (不证明了)
当负数在进行除法移位时(除数为2的幂) ,(a<0) ,在进行下列公式转换后才能进行移位
[a/2^n] = ⌈a/2^n⌉ = ⌊(a+2^n-1) / 2^n⌋
这也是为什么要 and edx, 7 add eax.edx 的原因