VC++使用三种语法来完成循环结构,分别为do、while、for;
- do循环:先执行循环体,后比较循环
- while循环:先比较循环,执行循环体
- for循环:先初始化再比较判断,最后执行循环体
运行环境:
- 操作系统: Windows 7家庭版
- 编译器:VC6 VS2013
循环
do
特点包括:
1 2 3 4
| DO_BEGIN: ...... 代码 jxx DO_BEGIN ;减量跳转,if为增量跳转 DO_END
|
首先分析Debug版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| // Test.cpp : Defines the entry point for the console application. //
#include "stdafx.h" #include <stdlib.h> int main(int argc, char* argv[]) { int n = 0; int nSum = 0; do { nSum = nSum + n; n++; } while (n <= 100); printf("Hello World!\n"); return 0; }
8: int n = 0; 00401028 mov dword ptr [ebp-4],0 9: int nSum = 0; 0040102F mov dword ptr [ebp-8],0 10: do 11: { 12: nSum = nSum + n; 00401036 mov eax,dword ptr [ebp-8] 00401039 add eax,dword ptr [ebp-4] 0040103C mov dword ptr [ebp-8],eax 13: n++; 0040103F mov ecx,dword ptr [ebp-4] 00401042 add ecx,1 00401045 mov dword ptr [ebp-4],ecx 14: } while (n <= 100); 00401048 cmp dword ptr [ebp-4],64h 0040104C jle main+26h (00401036) ;减量跳转 15: printf("Hello World!\n"); 0040104E push offset string "Hello World!\n" (0042201c) 00401053 call printf (00401080) 00401058 add esp,4 16: return 0; 0040105B xor eax,eax
|
while
代码定式:
1 2 3 4 5
| WHILE_BEGIN: jxx WHILE_END ..... jmp WHILE_BEGIN WHILE_END:
|
首先分析Debug版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| int main(int argc, char* argv[]) { int n = 0; int nSum = 0; while(n <= 100) { nSum = nSum + n; n++; } printf("Hello World!\n"); return 0; }
22: int n = 0; 004010B8 mov dword ptr [ebp-4],0 23: int nSum = 0; 004010BF mov dword ptr [ebp-8],0 24: while(n <= 100) 004010C6 cmp dword ptr [ebp-4],64h ;上界 004010CA jg main+40h (004010e0) 25: { 26: nSum = nSum + n; 004010CC mov eax,dword ptr [ebp-8] 004010CF add eax,dword ptr [ebp-4] 004010D2 mov dword ptr [ebp-8],eax 27: n++; 004010D5 mov ecx,dword ptr [ebp-4] 004010D8 add ecx,1 004010DB mov dword ptr [ebp-4],ecx 28: } 004010DE jmp main+26h (004010c6) ;下界 29: printf("Hello World!\n"); 004010E0 push offset string "Hello World!\n" (0042201c) 004010E5 call printf (00401120) 004010EA add esp,4 30: return 0;
|
for
代码定式:
1 2 3 4 5 6 7 8 9 10 11 12
| FOR_INIT: n = 1; nSum = 0; jmp FOR_CMP FOR_STEP: n++; FOR_CMP: n <= 100; jxx jxx FOR_END nSum = nSum + n jmp FOR_STEP JMP_END:
|
分析Debug版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| int main(int argc, char* argv[]) { for (int n = 1, nSum = 0;n <= 100; n++) { nSum = nSum + n; } printf("Hello World!\n"); return 0; }
36: 37: for (int n = 1, nSum = 0;n <= 100; n++) 0040D7C8 mov dword ptr [ebp-4],1 0040D7CF mov dword ptr [ebp-8],0 0040D7D6 jmp main+31h (0040d7e1) //初始化部分 0040D7D8 mov eax,dword ptr [ebp-4] 0040D7DB add eax,1 //循环加1 0040D7DE mov dword ptr [ebp-4],eax 0040D7E1 cmp dword ptr [ebp-4],64h 0040D7E5 jg main+42h (0040d7f2) //比较部分 38: { 39: nSum = nSum + n; 0040D7E7 mov ecx,dword ptr [ebp-8] //循环体 0040D7EA add ecx,dword ptr [ebp-4] 0040D7ED mov dword ptr [ebp-8],ecx 40: } 0040D7F0 jmp main+28h (0040d7d8) //跳回比较 41: printf("Hello World!\n"); 0040D7F2 push offset string "Hello World!\n" (0042201c) 0040D7F7 call printf (00401120) 0040D7FC add esp,4 42: return 0; 0040D7FF xor eax,eax
|
所有的循环在Release中都会被优化为do.while
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| .text:00401000 ; int __cdecl main(int argc, const char **argv, const char **envp) .text:00401000 _main proc near ; CODE XREF: start+AF↓p .text:00401000 .text:00401000 argc = dword ptr 4 .text:00401000 argv = dword ptr 8 .text:00401000 envp = dword ptr 0Ch .text:00401000 .text:00401000 mov eax, 1 .text:00401005 xor ecx, ecx .text:00401007 .text:00401007 loc_401007: ; CODE XREF: _main+D↓j .text:00401007 add ecx, eax .text:00401009 inc eax .text:0040100A cmp eax, 64h .text:0040100D jle short loc_401007 .text:0040100F xor eax, eax .text:00401011 retn .text:00401011 _main endp .text:00401011
|