设为首页 加入收藏

TOP

5.7 do/while/for的比较(1)
2013-10-07 14:30:09 来源: 作者: 【 】 浏览:57
Tags:5.7 do/while/for 比较

5.7 do/while/for的比较(1)

VC++(www.cppentry.com)使用三种语法来完成循环结构,分别为为do、while、for。虽然它们完成的功能都是循环,但是每种语法有着不同的执行流程。

do循环:先执行循环体,后比较判断。

while循环:先比较判断,后执行循环体。

for循环:先初始化,再比较判断,最后执行循环体。

对每种结构进行分析,了解它们生成的汇编代码,它们之间的区别,以及如何根据每种循环结构的特性进行还原。

(1)do循环

do循环的工作流程清晰,识别起来也相对简单。根据其特性,先执行语句块,再进行比较判断。当条件成立时,会继续执行语句块。C++(www.cppentry.com)中的goto语句也可以用来模拟do循环结构,如代码清单5-21所示。

代码清单5-21 使用goto语句模拟do循环

  1. // goto模拟do循环完成正数累加和  
  2. int GoToDo(int nCount){  
  3.     int nSum = 0;  
  4.     int nIndex = 0;  
  5. // 用于goto语句跳转使用标记  
  6. GOTO_DO:  
  7.     // 此处为循环语句块  
  8.     nSum += nIndex;     // 保存每次累加和  
  9.     nIndex++;               // 指定循环步长为每次递增1  
  10.     // 若nIndex大于nCount,则结束goto调用  
  11.     if (nIndex <= nCount){  
  12.         goto GOTO_DO;  
  13.     }  
  14.     return nSum;                // 返回结果  

代码清单5-21演示了使用goto语句与if分支结构来实现do循环过程。程序执行流程是自上向下地顺序执行代码,通过goto语句向上跳转修改程序流程,实现循环。do循环结构也是如此,如代码清单5-22所示。

代码清单5-22 do循环—Debug版

  1. // C++(www.cppentry.com)源码说明:do循环完成整数累加和  
  2. int LoopDO(int nCount){  
  3.     int nSum = 0;  
  4.     int nIndex = 0;  
  5.     do {  
  6.         nSum += nIndex;  
  7.         nIndex++;  
  8.     // 循环判断,是否结束循环体  
  9.     } while(nIndex <= nCount);  
  10.     return nSum;  
  11. }  
  12.  
  13. // C++(www.cppentry.com)源码与对应汇编代码讲解  
  14. // C++(www.cppentry.com)源码对比,变量初始化  
  15. int nSum = 0;  
  16. 0040B4D8   mov         dword ptr [ebp-4],0  
  17. int nIndex = 0;  
  18. 0040B4DF   mov         dword ptr [ebp-8],0  
  19. // C++(www.cppentry.com)源码对比,进入循环语句块  
  20. do{  
  21. nSum += nIndex;  
  22. ; 循环语句块的首地址,即循环跳转地址  
  23. 0040B4E6   mov         eax,dword ptr [ebp-4]  
  24. 0040B4E9   add         eax,dword ptr [ebp-8]  
  25. 0040B4EC   mov         dword ptr [ebp-4],eax  
  26. nIndex++;  
  27. 0040B4EF   mov         ecx,dword ptr [ebp-8]  
  28. 0040B4F2   add         ecx,1  
  29. 0040B4F5   mov         dword ptr [ebp-8],ecx  
  30. // C++(www.cppentry.com)源码对比,比较是否结束循环  
  31. } while(nIndex <= nCount);  
  32. 0040B4F8   mov         edx,dword ptr [ebp-8]  
  33. ; 比较两个内存中的数据  
  34. 0040B4FB   cmp         edx,dword ptr [ebp+8]  
  35. ; 根据比较结果,使用条件跳转指令JLE,小于等于则跳转到地址0x0040B4E6处  
  36. 0040B4FE   jle         LoopDO+26h (0040b4e6)  
  37. return nSum;  
  38. 0040B500   mov         eax,dword ptr [ebp-4] 

代码清单5-22中的循环比较语句“while(nIndex <= nCount)”转换成的汇编代码和if分支结构非常相似,分析后发现它们并不相同。if语句的比较是相反的,并且跳转地址大于当前代码的地址,是一个向下跳转的过程;而do中的跳转地址小于当前代码的地址,是一个向上跳转的过程,所以条件跳转的逻辑与源码中的逻辑相同。有了这个特性,if语句与do循环判断就很好区分了。

总结:

  1. DO_BEGIN:  
  2. ……          ; 循环语句块  
  3. ; 影响标记位的指令  
  4. jxx DO_BEGIN    ; 向上跳转 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇5.4 switch的真相(1) 下一篇5.5 难以构成跳转表的switch(3)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: