乘法运算

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

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

int main(int argc,char *argv)
{
    int nVarOne = argc;
    int nVarTwo = argc;

    // 变量乘常量 (非2的幂)
    printf("nVarOne * 11 = %d\n", nVarOne * 11);
    // 变量乘常量 (2的幂)
    printf("nVarOne * 16 = %d\n", nVarOne * 16);
    // 常量*常量
    printf("55 * 11 = %d\n", 55 * 11);
    // 复合运算
    printf("nVarOne * 8 + 5 = %d\n", nVarOne * 8 + 5);
    // 变量*变量
    printf("nVarOne*nVarTwo = %d\n", nVarOne*nVarTwo);

    std::cout << "Hello World!\n"; 
    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\n", nVarOne * 11);
008D2684  imul        eax,dword ptr [nVarOne],0Bh  
008D2688  push        eax  
008D2689  push        offset string "nVarOne * 11 = %d\n" (08D9B30h)  
008D268E  call        _printf (08D1055h)  
008D2693  add         esp,8  
    // 变量乘常量 (2的幂)
    printf("nVarOne * 16 = %d\n", nVarOne * 16);
008D2696  mov         eax,dword ptr [nVarOne]  
008D2699  shl         eax,4  
008D269C  push        eax  
008D269D  push        offset string "nVarOne * 16 = %d\n" (08D9B48h)  
008D26A2  call        _printf (08D1055h)  
008D26A7  add         esp,8  
    // 常量*常量
    printf("55 * 11 = %d\n", 55 * 11);
008D26AA  push        25Dh  
008D26AF  push        offset string "55 * 11 = %d\n" (08D9B60h)  
008D26B4  call        _printf (08D1055h)  
008D26B9  add         esp,8  
    // 复合运算
    printf("nVarOne * 8 + 5 = %d\n", 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\n" (08D9B70h)  
008D26CC  call        _printf (08D1055h)  
008D26D1  add         esp,8  
    // 变量*变量
    printf("nVarOne*nVarTwo = %d\n", nVarOne*nVarTwo);
008D26D4  mov         eax,dword ptr [nVarOne]  
008D26D7  imul        eax,dword ptr [nVarTwo]  
008D26DB  push        eax  
008D26DC  push        offset string "nVarOne*nVarTwo = %d\n" (08D9B8Ch)  
008D26E1  call        _printf (08D1055h)  
008D26E6  add         esp,8  

    std::cout << "Hello World!\n"; 
008D26E9  push        offset string "Hello World!\n" (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\n"
.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\n"
.text:00401060                 call    _printf
.text:00401065                 push    25Dh
.text:0040106A                 push    offset a5511D   ; "55 * 11 = %d\n"
.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\n"
.text:00401081                 call    _printf
.text:00401086                 imul    esi, esi
.text:00401089                 push    esi
.text:0040108A                 push    offset _Val     ; "nVarOne*nVarTwo = %d\n"
.text:0040108F                 call    _printf
.text:00401094                 mov     ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@[email protected] ; _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"

猜你喜欢

转载自www.cnblogs.com/xiangtingshen/p/11163498.html