C++反汇编中的循环语句
do while
效率是最高的
#include "pch.h" #include <iostream> int main() { int nVarTemp = 0; int nSum = 0; do { nSum += nVarTemp; nVarTemp++; } while (nVarTemp < 101); printf("nSum = %d;nVarTemp = %d", nSum, nVarTemp); std::cout << "Hello World!\n"; }
用ida打开
.text:00412640 push ebp .text:00412641 mov ebp, esp .text:00412643 sub esp, 0D8h .text:00412649 push ebx .text:0041264A push esi .text:0041264B push edi .text:0041264C lea edi, [ebp+var_D8] .text:00412652 mov ecx, 36h .text:00412657 mov eax, 0CCCCCCCCh .text:0041265C rep stosd .text:0041265E mov ecx, offset unk_41E008 .text:00412663 call sub_41127B .text:00412668 mov [ebp+var_8], 0 .text:0041266F mov [ebp+var_14], 0 .text:00412676 .text:00412676 loc_412676: ; CODE XREF: sub_412640+4C↓j .text:00412676 mov eax, [ebp+var_14] .text:00412679 add eax, [ebp+var_8] .text:0041267C mov [ebp+var_14], eax .text:0041267F mov eax, [ebp+var_8] .text:00412682 add eax, 1 .text:00412685 mov [ebp+var_8], eax .text:00412688 cmp [ebp+var_8], 65h .text:0041268C jl short loc_412676 .text:0041268E mov eax, [ebp+var_8] .text:00412691 push eax .text:00412692 mov ecx, [ebp+var_14] .text:00412695 push ecx .text:00412696 push offset aNsumDNvartempD ; "nSum = %d;nVarTemp = %d" .text:0041269B call sub_411055 .text:004126A0 add esp, 0Ch .text:004126A3 push offset Str ; "Hello World!\n" .text:004126A8 mov eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout .text:004126AD push eax ; int .text:004126AE call sub_411212 .text:004126B3 add esp, 8 .text:004126B6 xor eax, eax .text:004126B8 pop edi .text:004126B9 pop esi .text:004126BA pop ebx .text:004126BB add esp, 0D8h .text:004126C1 cmp ebp, esp .text:004126C3 call sub_411285 .text:004126C8 mov esp, ebp .text:004126CA pop ebp .text:004126CB retn .text:004126CB sub_412640 endp
while
int main() { int nVarTemp = 0; int nSum = 0; while (nVarTemp < 101) { nSum += nVarTemp; nVarTemp++; } printf("nSum = %d;nVarTemp = %d", nSum, nVarTemp); std::cout << "Hello World!\n"; }
debug版本
.text:00412640 .text:00412640 var_D8 = byte ptr -0D8h .text:00412640 var_14 = dword ptr -14h .text:00412640 var_8 = dword ptr -8 .text:00412640 .text:00412640 push ebp .text:00412641 mov ebp, esp .text:00412643 sub esp, 0D8h .text:00412649 push ebx .text:0041264A push esi .text:0041264B push edi .text:0041264C lea edi, [ebp+var_D8] .text:00412652 mov ecx, 36h .text:00412657 mov eax, 0CCCCCCCCh .text:0041265C rep stosd .text:0041265E mov ecx, offset unk_41E009 .text:00412663 call sub_41127B .text:00412668 mov [ebp+var_8], 0 .text:0041266F mov [ebp+var_14], 0 .text:00412676 .text:00412676 loc_412676: ; CODE XREF: sub_412640+4E↓j .text:00412676 cmp [ebp+var_8], 65h .text:0041267A jge short loc_412690 .text:0041267C mov eax, [ebp+var_14] .text:0041267F add eax, [ebp+var_8] .text:00412682 mov [ebp+var_14], eax .text:00412685 mov eax, [ebp+var_8] .text:00412688 add eax, 1 .text:0041268B mov [ebp+var_8], eax .text:0041268E jmp short loc_412676 .text:00412690 ; --------------------------------------------------------------------------- .text:00412690 .text:00412690 loc_412690: ; CODE XREF: sub_412640+3A↑j .text:00412690 mov eax, [ebp+var_8] .text:00412693 push eax .text:00412694 mov ecx, [ebp+var_14] .text:00412697 push ecx .text:00412698 push offset aNsumDNvartempD ; "nSum = %d;nVarTemp = %d" .text:0041269D call sub_411055 .text:004126A2 add esp, 0Ch .text:004126A5 push offset Str ; "Hello World!\n" .text:004126AA mov eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout .text:004126AF push eax ; int .text:004126B0 call sub_411212 .text:004126B5 add esp, 8 .text:004126B8 xor eax, eax .text:004126BA pop edi .text:004126BB pop esi .text:004126BC pop ebx .text:004126BD add esp, 0D8h .text:004126C3 cmp ebp, esp .text:004126C5 call sub_411285 .text:004126CA mov esp, ebp .text:004126CC pop ebp .text:004126CD retn .text:004126CD sub_412640 endp
release版本,编译器对while语句进行优化,优化成do while结构
text:00401040 _main proc near ; CODE XREF: __scrt_common_main_seh+F5↓p .text:00401040 push esi ; _Val .text:00401041 xor edx, edx .text:00401043 xor esi, esi .text:00401045 xor eax, eax .text:00401047 .text:00401047 loc_401047: ; CODE XREF: _main+12↓j .text:00401047 inc esi .text:00401048 add edx, eax .text:0040104A add esi, eax .text:0040104C add eax, 2 .text:0040104F cmp eax, 64h .text:00401052 jl short loc_401047 .text:00401054 cmp eax, 65h .text:00401057 lea ecx, [eax+1] .text:0040105A cmovge ecx, eax .text:0040105D push ecx .text:0040105E xor ecx, ecx .text:00401060 cmp eax, 65h .text:00401063 cmovge eax, ecx .text:00401066 add eax, esi .text:00401068 add eax, edx .text:0040106A push eax .text:0040106B push offset _Format ; "nSum = %d;nVarTemp = %d" .text:00401070 call _printf .text:00401075 mov ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A.gap0 ; _Ostr .text:0040107B add esp, 0Ch .text:0040107E 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:00401083 xor eax, eax .text:00401085 pop esi .text:00401086 retn .text:00401086 _main endp
for
效率比较低
int main() { int nVarTemp = 0; int nSum = 0; for (;nVarTemp < 101;) { nSum += nVarTemp; nVarTemp++; } printf("nSum = %d;nVarTemp = %d", nSum, nVarTemp); std::cout << "Hello World!\n"; }
debug
.text:00412640 .text:00412640 var_D8 = byte ptr -0D8h .text:00412640 var_14 = dword ptr -14h .text:00412640 var_8 = dword ptr -8 .text:00412640 .text:00412640 push ebp .text:00412641 mov ebp, esp .text:00412643 sub esp, 0D8h .text:00412649 push ebx .text:0041264A push esi .text:0041264B push edi .text:0041264C lea edi, [ebp+var_D8] .text:00412652 mov ecx, 36h .text:00412657 mov eax, 0CCCCCCCCh .text:0041265C rep stosd .text:0041265E mov ecx, offset unk_41E008 .text:00412663 call sub_41127B .text:00412668 mov [ebp+var_8], 0 .text:0041266F mov [ebp+var_14], 0 .text:00412676 .text:00412676 for_if: ; CODE XREF: sub_412640+4E↓j .text:00412676 cmp [ebp+var_8], 65h .text:0041267A jge short for_end .text:0041267C mov eax, [ebp+var_14] .text:0041267F add eax, [ebp+var_8] .text:00412682 mov [ebp+var_14], eax .text:00412685 mov eax, [ebp+var_8] .text:00412688 add eax, 1 .text:0041268B mov [ebp+var_8], eax .text:0041268E jmp short for_if .text:00412690 ; --------------------------------------------------------------------------- .text:00412690 .text:00412690 for_end: ; CODE XREF: sub_412640+3A↑j .text:00412690 mov eax, [ebp+var_8] .text:00412693 push eax .text:00412694 mov ecx, [ebp+var_14] .text:00412697 push ecx .text:00412698 push offset aNsumDNvartempD ; "nSum = %d;nVarTemp = %d" .text:0041269D call sub_411055 .text:004126A2 add esp, 0Ch .text:004126A5 push offset Str ; "Hello World!\n" .text:004126AA mov eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout .text:004126AF push eax ; int .text:004126B0 call sub_411212 .text:004126B5 add esp, 8 .text:004126B8 xor eax, eax .text:004126BA pop edi .text:004126BB pop esi .text:004126BC pop ebx .text:004126BD add esp, 0D8h .text:004126C3 cmp ebp, esp .text:004126C5 call sub_411285 .text:004126CA mov esp, ebp .text:004126CC pop ebp .text:004126CD retn .text:004126CD sub_412640 endp
同样编译器对release版本,将for循环优化为 do while 结构
.text:00401040 ; int __cdecl main() .text:00401040 _main proc near ; CODE XREF: __scrt_common_main_seh+F5↓p .text:00401040 push esi ; _Val .text:00401041 xor edx, edx .text:00401043 xor esi, esi .text:00401045 xor eax, eax .text:00401047 .text:00401047 loc_401047: ; CODE XREF: _main+12↓j .text:00401047 inc esi .text:00401048 add edx, eax .text:0040104A add esi, eax .text:0040104C add eax, 2 .text:0040104F cmp eax, 64h .text:00401052 jl short loc_401047 .text:00401054 cmp eax, 65h .text:00401057 lea ecx, [eax+1] .text:0040105A cmovge ecx, eax .text:0040105D push ecx .text:0040105E xor ecx, ecx .text:00401060 cmp eax, 65h .text:00401063 cmovge eax, ecx .text:00401066 add eax, esi .text:00401068 add eax, edx .text:0040106A push eax .text:0040106B push offset _Format ; "nSum = %d;nVarTemp = %d" .text:00401070 call _printf .text:00401075 mov ecx, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A.gap0 ; _Ostr .text:0040107B add esp, 0Ch .text:0040107E 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:00401083 xor eax, eax .text:00401085 pop esi .text:00401086 retn .text:00401086 _main endp .text:00401086