乘法运算
无符号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@@@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"