03 有符号数除以非2的幂

 

 

 

右移是向下取整操作,对于除法A/C,当C>0C不是2的幂时,除法转乘法(magic无进位)

    if (A > 0) {

        AM >> n; //正数直接右移

    }

    else {

        (AM >> n) + 1; //负数右移后要 +1

    }

 

还原:

2^33 / 66666667h 5

int nVal = argc/5;

 

 

 还原:

2^32 / 55555556h3

int nVal = argc/3;

 

 

有符号数*无符号数的计算方法:

16bit举例,有符号数A * 无符号数8086h ,如果用imul指令,相当于把8086h视为负数

A * 8086 = A * -(10000h-8086h)

              = A*(8086h-10000h)

              = 8086*A - 10000*A  =>  dx.ax

结果再加10000*A才等于8086*A,相当于dx再加A

8086*A - 10000*A + 10000*A  => add dx, A

 

       mov     eax, 0x80868086

       mov     ecx, 0x123     

       imul    ecx            

       add     edx, ecx

 

 

 

 

A/(-2^n) = -(A/2^n)

 

 

 计算A/C, C>0, 可转换为(A*M)>>n,

C<0, 可转换为 -((A*M)>>n), (A*(-M))>>n

 

 

 magic为正,imulsar之间出现对edx的减调整,说明除数为负。

2^34/neg(magic) => argc/-7

 

 

Magic大于0,在imulsar之间存在对edx的减调整
或者
Magic小于0,在imulsar之间没有调整
皆判定除数为负

 

 

 

优化除法:

 

1. 除数为正数

 

    1.1 无符号除法

 

        1.1.1 除数为2的幂:shr

 

        1.1.2 除数为非2的幂

 

            1.1.2.1 magic无进位:mul, shr

 

            1.1.2.2 magic有进位:mul, sub, shr, add, shr

 

    1.2 有符号除法

 

        1.2.1 除数为2的幂:cdq, and, add, shr

 

        1.2.2 除数为非2的幂

 

            1.2.2.1 magic为正数:imul, sar

 

            1.2.2.2 magic为负数:imul, add, sar

 

2. 除数为负数

 

    2.1 除数为2的幂:cdq, and, add, sar, neg

 

    2.2 除数为非2的幂

 

        2.2.1 magic为正数:imul, sar

 

        2.2.2 magic为负数:imul, add, sar

 

posted @ 2020-12-07 13:37  八转达人  阅读(199)  评论(0编辑  收藏  举报