除法-cdq和移位(除数为2的幂)

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 的原因

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值