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!
"; 
}

用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!
"
.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!
";
}

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!
"
.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!
";
}

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!
"
.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
原文地址:https://www.cnblogs.com/xiangtingshen/p/11298708.html