取模

经典的取绝对值方式

cdq
	xor         eax, edx    ;edx=0 xor 0值不变  edx=1 xor 1就是取反
    sub         eax, edx    ;edx=0 sub 0值不变  edx=1 sub -1就是加1,如果被除数是负数则是取反加1,那就是取绝对值了

取模优化

有符号

带幂优化

优化思路有两种
第一种带分支的:就是余数<除数 而除数是2的幂,所以余数是多少可以看二进制的末尾几位是多少那余数就是多少
如 10/4===0000 1010/4 因为除数是4所以直接后面的两位就是余数,同理除数是8取后面的3位就可以了
因为是有符号数,所以要考虑符号位的情况,还有取模0的情况

第二种不带分支的:直接利用取绝对值的方式后进行取余数,然后再根据取绝对值的方式(取反+1)来改变余数的正负,余数的正负是根据被除数来决定的
int main(int argc)
{
	//第一种优化方式
    printf("%d\n", argc % 2);
    /*
    mov         eax,dword ptr [argc]
    and         eax,80000001h             ;因为是除以2的幂,所以取位数(位数又除数来决定是多少位)就知道余多少,例如10/4,看10的二进制最后二位是多少,那就是余数
    jns         main+2Dh (0F513EDh)       ;如果符号位S不为1(正数),就跳转,下面条件是处理负数的,改变负数的符号位和0的特殊情况
    dec         eax                       ;处理负数取模为0的指令 -1后全f,如果取模不为0的情况是不需要dec和inc指令的
    or          eax,0FFFFFFFEh            ;负数的符号位
    inc         eax                       ;处理负数取模为0的指令 全f后+1就是0了,溢出
    mov         esi,esp 0F513ED-END
    push        eax
    push        0F55858h
    call        dword ptr ds:[0F59114h]
    */

}
int main(int argc)
{
	//第二种优化方式
    printf("%d\n", argc % -2);
    /*
    mov         eax, dword ptr[argc]
    cdq
    xor         eax, edx    ;edx=0 xor 0值不变  edx=1 xor 1就是取反
    sub         eax, edx    ;edx=0 sub 0值不变  edx=1 sub -1就是加1,如果被除数是负数则是取反加1,那就是取绝对值了
    and         eax, 1      ;取余数
    xor         eax, edx    ;对余数一次取反加1,正数不变,这就要看被除数是正还是负了,被除数是正,余数就为正
    sub         eax, edx
    push        eax
    push        11D0DC4h
    */
}

不带幂的优化

思路就是用公式 余数=被除数-*除数
int main(int argc)
{
    printf("%d", argc % 7);
    /*
    mov         esi, dword ptr[argc]
    mov         eax, 92492493h  //magicNumber为正
    imul        esi
    add         edx, esi
    sar         edx, 2
    mov         eax, edx
    shr         eax, 1Fh
    add         eax, edx        利用除法得到商
    lea         ecx, [eax * 8]  商*(除数+1)就多了一个商
    sub         ecx, eax        减去一个商就是原来的 商*除数
    mov         eax, esi        
    sub         eax, ecx        被除数-商*除数=余数
    push        eax
    push        12B0DC4h
    call        printf(012A106Fh)
    */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值