• 乘法运算


    无符号mul和有符号imul,在编译的过程中,先尝试将乘法转换成加法

    或使用移位指令等周期转移较短的指令,如果都没有才用乘法指令

    int main(int argc,char *argv)
    {
        int nVarOne = argc;
        int nVarTwo = argc;
    
        // 变量乘常量 (非2的幂)
        printf("nVarOne * 11 = %d
    ", nVarOne * 11);
        // 变量乘常量 (2的幂)
        printf("nVarOne * 16 = %d
    ", nVarOne * 16);
        // 常量*常量
        printf("55 * 11 = %d
    ", 55 * 11);
        // 复合运算
        printf("nVarOne * 8 + 5 = %d
    ", nVarOne * 8 + 5);
        // 变量*变量
        printf("nVarOne*nVarTwo = %d
    ", nVarOne*nVarTwo);
    
        std::cout << "Hello World!
    "; 
        system("pause");
    }

    Debug版本反汇编:

    int main(int argc,char *argv)
    {
    008D2650  push        ebp  
    008D2651  mov         ebp,esp  
    008D2653  sub         esp,0D8h  
    008D2659  push        ebx  
    008D265A  push        esi  
    008D265B  push        edi  
    008D265C  lea         edi,[ebp-0D8h]  
    008D2662  mov         ecx,36h  
    008D2667  mov         eax,0CCCCCCCCh  
    008D266C  rep stos    dword ptr es:[edi]  
    008D266E  mov         ecx,offset _E6D683D6_mul@cpp (08DE008h)  
    008D2673  call        @__CheckForDebuggerJustMyCode@4 (08D1280h)  
        int nVarOne = argc;
    008D2678  mov         eax,dword ptr [argc]  
    008D267B  mov         dword ptr [nVarOne],eax  
        int nVarTwo = argc;
    008D267E  mov         eax,dword ptr [argc]  
    008D2681  mov         dword ptr [nVarTwo],eax  
    
        // 变量乘常量 (非2的幂)
        printf("nVarOne * 11 = %d
    ", nVarOne * 11);
    008D2684  imul        eax,dword ptr [nVarOne],0Bh  
    008D2688  push        eax  
    008D2689  push        offset string "nVarOne * 11 = %d
    " (08D9B30h)  
    008D268E  call        _printf (08D1055h)  
    008D2693  add         esp,8  
        // 变量乘常量 (2的幂)
        printf("nVarOne * 16 = %d
    ", nVarOne * 16);
    008D2696  mov         eax,dword ptr [nVarOne]  
    008D2699  shl         eax,4  
    008D269C  push        eax  
    008D269D  push        offset string "nVarOne * 16 = %d
    " (08D9B48h)  
    008D26A2  call        _printf (08D1055h)  
    008D26A7  add         esp,8  
        // 常量*常量
        printf("55 * 11 = %d
    ", 55 * 11);
    008D26AA  push        25Dh  
    008D26AF  push        offset string "55 * 11 = %d
    " (08D9B60h)  
    008D26B4  call        _printf (08D1055h)  
    008D26B9  add         esp,8  
        // 复合运算
        printf("nVarOne * 8 + 5 = %d
    ", nVarOne * 8 + 5);
    008D26BC  mov         eax,dword ptr [nVarOne]  
    008D26BF  lea         ecx,[eax*8+5]  
    008D26C6  push        ecx  
    008D26C7  push        offset string "nVarOne * 8 + 5 = %d
    " (08D9B70h)  
    008D26CC  call        _printf (08D1055h)  
    008D26D1  add         esp,8  
        // 变量*变量
        printf("nVarOne*nVarTwo = %d
    ", nVarOne*nVarTwo);
    008D26D4  mov         eax,dword ptr [nVarOne]  
    008D26D7  imul        eax,dword ptr [nVarTwo]  
    008D26DB  push        eax  
    008D26DC  push        offset string "nVarOne*nVarTwo = %d
    " (08D9B8Ch)  
    008D26E1  call        _printf (08D1055h)  
    008D26E6  add         esp,8  
    
        std::cout << "Hello World!
    "; 
    008D26E9  push        offset string "Hello World!
    " (08D9BA8h)  
    008D26EE  mov         eax,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (08DD0C8h)]  
    008D26F3  push        eax  
    008D26F4  call        std::operator<<<std::char_traits<char> > (08D1217h)  
    008D26F9  add         esp,8  
        system("pause");
    008D26FC  mov         esi,esp  
    008D26FE  push        offset string "pause" (08D9BB8h)  
    008D2703  call        dword ptr [__imp__system (08DD1C4h)]  
    008D2709  add         esp,4  
        system("pause");
    008D270C  cmp         esi,esp  
    008D270E  call        __RTC_CheckEsp (08D128Ah)  
    }

    release版本通过ida查看

    text:00401040                 push    ebp
    .text:00401041                 mov     ebp, esp
    .text:00401043                 push    esi
    .text:00401044                 mov     esi, [ebp+argc]
    .text:00401047                 imul    eax, esi, 0Bh
    .text:0040104A                 push    eax
    .text:0040104B                 push    offset _Format  ; "nVarOne * 11 = %d
    "
    .text:00401050                 call    _printf
    .text:00401055                 mov     eax, esi
    .text:00401057                 shl     eax, 4
    .text:0040105A                 push    eax
    .text:0040105B                 push    offset aNvarone16D ; "nVarOne * 16 = %d
    "
    .text:00401060                 call    _printf
    .text:00401065                 push    25Dh
    .text:0040106A                 push    offset a5511D   ; "55 * 11 = %d
    "
    .text:0040106F                 call    _printf
    .text:00401074                 lea     eax, ds:5[esi*8]
    .text:0040107B                 push    eax
    .text:0040107C                 push    offset aNvarone85D ; "nVarOne * 8 + 5 = %d
    "
    .text:00401081                 call    _printf
    .text:00401086                 imul    esi, esi
    .text:00401089                 push    esi
    .text:0040108A                 push    offset _Val     ; "nVarOne*nVarTwo = %d
    "
    .text:0040108F                 call    _printf
    .text:00401094                 mov     ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A.gap0 ; _Ostr
    .text:0040109A                 call    ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char const *)
    .text:0040109F                 push    offset Command  ; "pause"
  • 相关阅读:
    理解 RESTful:理论与最佳实践
    Shiro 性能优化:解决 Session 频繁读写问题
    单点登录的三种实现方式
    理解 Spring(二):AOP 的概念与实现原理
    理解 Spring(一):Spring 与 IoC
    MFC查内存泄漏方法
    024 --- 第28章 访问者模式
    023 --- 第27章 解释器模式
    022 --- 第26章 享元模式
    021 --- 第25章 中介者模式
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/11163498.html
Copyright © 2020-2023  润新知