用汇编的眼光看C++(之循环流程)

发表于:2012-5-18 09:23

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:feixiaoxing    来源:51Testing软件测试网采编

  循环是我们编程中遇到的另外一项重要技术。通过反复的迭代运算,我们可以获取想要的任何结果。当然这种迭代是有基本条件的,或是以时间为条件的,或是以空间为条件的,或者是某一种外来交互作为条件的。循环的方式有很多种,但是常用的还是:while、for、do-while、goto这几种。很多公司的项目都不喜欢goto,这其中倒不是说goto不好,主要是goto的随意性太大,一旦用的不好,就会降低代码的可读性,反而影响其他人的工作效率。

  (1)do-while为什么先执行,后判断?

  老规矩,我们还是先看代码示例再说:

21:       int m = 10;
00401638   mov         dword ptr [ebp-4],0Ah
22:       do {
23:           printf("%d\n", m);
0040163F   mov         eax,dword ptr [ebp-4]
00401642   push        eax
00401643   push        offset string "%d\n" (0046f01c)
00401648   call        printf (00420fb0)
0040164D   add         esp,8
24:           m ++;
00401650   mov         ecx,dword ptr [ebp-4]
00401653   add         ecx,1
00401656   mov         dword ptr [ebp-4],ecx
25:       }while(m < 10);
00401659   cmp         dword ptr [ebp-4],0Ah
0040165D   jl          process+1Fh (0040163f)

  如果换成while呢?

21:       int m = 10;
00401638   mov         dword ptr [ebp-4],0Ah
22:       while(m < 20)
0040163F   cmp         dword ptr [ebp-4],14h
00401643   jge         process+41h (00401661)
23:       {
24:           printf("%d\n", m);
00401645   mov         eax,dword ptr [ebp-4]
00401648   push        eax
00401649   push        offset string "%d\n" (0046f01c)
0040164E   call        printf (00420fb0)
00401653   add         esp,8
25:           m ++;
00401656   mov         ecx,dword ptr [ebp-4]
00401659   add         ecx,1
0040165C   mov         dword ptr [ebp-4],ecx
26:       }
0040165F   jmp         process+1Fh (0040163f)
27:   }

  其实,上面的代码表现已经很明显了。do-while的时候,模块上来先进行运算,然后再判断数据范围的大小;while就不一样,上来就进行判断,判断成功就继续运行,否则就退出循环模块,如果是for的情况呢?

21:       for(int m = 10; m < 20; m++)
00401638   mov         dword ptr [ebp-4],0Ah
0040163F   jmp         process+2Ah (0040164a)
00401641   mov         eax,dword ptr [ebp-4]
00401644   add         eax,1
00401647   mov         dword ptr [ebp-4],eax
0040164A   cmp         dword ptr [ebp-4],14h
0040164E   jge         process+4Ch (0040166c)
22:       {
23:           printf("%d\n", m);
00401650   mov         ecx,dword ptr [ebp-4]
00401653   push        ecx
00401654   push        offset string "%d\n" (0046f01c)
00401659   call        printf (00420fc0)
0040165E   add         esp,8
24:           m ++;
00401661   mov         edx,dword ptr [ebp-4]
00401664   add         edx,1
00401667   mov         dword ptr [ebp-4],edx
25:       }
0040166A   jmp         process+21h (00401641)

  我们发现,其实for和上面的while,do-while有点小区别。在m第一次赋值的时候,并不进行加1处理,而是直接跳到地址0x40164a处运行,判断m数值和20进行判断。判断成功,则跳入循环模块,否则越过循环模块。那么,在循环处理结束后呢?也就是m++后,循环模块是怎么处理的?我们发现代码又回到了0x00401641处处理。但是这里并不是整个循环模块开始出的代码,而是对m进行自增处理。完成自增后,继续判断,下面的流程和第一次一样,不再赘述。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号