c&c++反汇编与逆向分析学习笔记(7)--乘法表达式

乘法运算对应的汇编指令有有符号imul和无符号mul两种。由于乘法指令的执行周期较长

,在编译过程中,编译器会先尝试将乘法转换成加法,或使用移位等周期较短的指令。当他们

都不可转换时,才会使用乘法指令。
    //C++源码说明
    //防止被视为无效代码,将每条运算作为printf参数使用
    //printf函数的讲解省略
    int nVarOne = argc;
    int nVarTwo = argc;

    //变量乘常量(常量值为非2的幂)
    printf("nVarOne * 15 = %d",nVarOne * 15);
    //变量乘常量(常量值为2的幂)
    printf("nVarOne * 16 = %d",nVarTwo * 16);
    //两常量相乘
    printf("2*2 = %d",2*2);
    //混合运算
    printf("nVarTwo * 4 +5 = %d",nVarTwo *4 + 5);
    //两变量相乘
    printf("nVarOne * nVarTwo = %d",nVarOne * nVarTwo);



    //Debug版本
    //C++
    printf("nVarOne * 15 = %d",nVarOne * 15);
    //反汇编
    mov edx,dword ptr [ebp-4]
    imul edx,edx,0Fh         //有符号数乘法
    //printf说明略

    //C++
    printf("nVarOne * 16 = %d",nVarTwo * 16);
    //反汇编
    mov eax,dword ptr [ebp-4]
    shl eax,4                 //利用左移运算符代替乘法运算
    //printf说明略

    //C++
    printf("2*2 = %d",2*2);
    //反汇编
    编译期间计算2*2,表达式转化为常量
    //printf函数
    push 4
    push offset string "2 * 2 = %d"
    call printf
    add esp,8

    //C++
    printf("nVarTwo * 4 +5 = %d",nVarTwo *4 + 5);
    //反汇编
    mov ecx,dword ptr [ebp-8]
    lea edx,[ecx*4+5]          //使用lea指令
    //printf说明略

    //C++
    printf("nVarOne * nVarTwo = %d",nVarOne * nVarTwo);
    //反汇编
    mov ecx,dword ptr [ebp-4]
    imul ecx,dword ptr [ebp-8]  //直接使用imul
    //printf说明略


    上面的例子中,乘法运算与加法运算的结合编译器采用LEA指令。此处,lea指令的目的不

是取地址。当这种组合运算中的乘数不等于2,4,8时编译器将采用另一种方式来处理。
    //C++
    printf("nVarTwo * 9 + 5 = %d",nVarTwo * 9 + 5);
    //反汇编
    mov eax,dword ptr [ebp-8]
    imul eax,eax,9
    add eax,5
    push eax
    push offset string "nVarTwo * 9 + 5 = %d"
    call printf
    add esp,8


    //在开启O2优化的Release版本中,除两个未知变量相乘无法优化,其余形式编译器都可

以优化。
    1》nVarOne * 15优化后等价于
    tmp = (nVarOne * 2)+nVarOne;
    result = (tmp * 4) + tmp;

    
    2》nVarTwo * 16优化同Debug版本
    3》2*2优化同Debug版本
    4》nVarOne * 4 + 5优化同Debug版本
    5》nVarTwo * 9优化后等价于
       nVarTwo * 1 + nVarTwo * 8//这样又可以采用lea指令进行运算了。
    6》nVarOne * nVarTwo同Debug一样无优化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值