设为首页 加入收藏

TOP

5.3 用if构成的多分支流程(1)
2013-10-07 14:30:27 来源: 作者: 【 】 浏览:67
Tags:5.3 构成 分支 流程

5.3 用if构成的多分支流程(1)

5.1节和5.2节介绍了由if与if…else…组成的分支结构。本节将介绍它们的组合形式—多分支结构。多分支结构类似于if…else…的组合方式,在if…else…的else之后再添加一个else if进行二次比较,这样就可以进行多次比较,再次选择程序流程,形成了多分支流程。它的C++(www.cppentry.com)语法格式为:if…else if…else if…,可重复后缀为else if。当最后为else时,便到了多分支结构的末尾处,不可再分支。通过代码清单5-6可以查看多分支结构的组成。

代码清单5-6 多分支结构—Debug版

  1. // C++(www.cppentry.com)源码说明:多分支结构  
  2. void IfElseIf(int argc){  
  3. if (argc > 0){              // 判断函数参数argc是否大于0  
  4.         printf("argc > 0");     // 比较成功后执行printf("argc > 0");  
  5. }else if (argc == 0){           // 判断函数参数argc是否等于0  
  6.         printf("argc == 0");        // 比较成功后执行printf("argc == 0");  
  7. }else{                  // 前两次比较都失败,则此条语句被执行  
  8.         printf("argc <= 0");          
  9.       }  
  10. }  
  11.  
  12. // C++(www.cppentry.com)源码与对应汇编代码讲解  
  13. // C++(www.cppentry.com)源码对比  
  14. if (argc > 0)  
  15. ; if比较转换  
  16. 00401108   cmp         dword ptr [ebp+8],0  
  17. ; 使用JLE条件跳转指令,如果判断后的结果小于等于0,则跳转到地址0x0040111D  
  18. 0040110C   jle         IfElseIf+2Dh (0040111d)  
  19. {  
  20. printf("argc > 0");  
  21. ; printf函数讲解略  
  22. 0040110E   push       offset string "argc > 0" (00420f9c)  
  23. 00401113   call        printf (00401150)  
  24. 00401118   add        esp,4  
  25. }else if (argc == 0)  
  26. ; 对应else,当上一条if语句被执行,执行JMP指令,跳转到地址0x0040113F处  
  27. ; 该地址为多分支结构结束地址,即最后一个else 或 else if的结束地址  
  28. 0040111B   jmp         IfElseIf+4Fh (0040113f)  
  29. ; if比较转换,使用条件跳转指令JNE,不等于0则跳转到地址0x00401132  
  30. 0040111D   cmp         dword ptr [ebp+8],0  
  31. 00401121   jne         IfElseIf+42h (00401132)  
  32. {  
  33. printf("argc == 0");  
  34. ; printf函数讲解略  
  35. 00401123   push       offset string "argc == 0" (0042003c)  
  36. 00401128   call        printf (00401150)  
  37. 0040112D   add        esp,4  
  38. }else  
  39. ; 跳转到多分支结构的结束地址  
  40. 00401130   jmp         IfElseIf+4Fh (0040113f)  
  41. {  
  42. printf("argc <= 0");  
  43. ; 注意,此处无判定。当以上各个条件均不成立时,以下代码则无条件执行  
  44.  
  45. ; 可将此处定义为最后的else块  
  46. 00401132   push       offset string "argc != 0" (00420030)  
  47. 00401137   call        printf (00401150)  
  48. 0040113C   add        esp,4  
  49. }  
  50. 0040113F   pop         edi 

代码清单5-6给出了if…else if…else 的组合。从代码中可以分析出,每条if语句由cmp和jxx组成,而else由一个jmp跳转到分支结构的最后一个语句块结束地址所组成。由此可见,虽然它们组合在了一起,但是每个if和else又都是独立的,if仍然是由CMP/TEST加jxx所组成,我们仍然可以根据上一节介绍的知识,利用jxx和jmp识别出if和else if语句块的边界,jxx指出了下一个else if的起始点,而jmp指出了整个多分支结构的末尾地址以及当前if或者else if语句块的末尾。最后的else块的边界也很容易识别,如果发现多分支块内的某一段代码在执行前没有判定,即可定义为else块,如上述代码中的00401132地址处。

总结:

  1. ; 会影响标志位的指令  
  2.         jxx ELSE_IF_BEGIN       ; 跳转到下一条else if语句块的首地址  
  3. IF_BEGIN:  
  4. ……                  ; if语句块内的执行代码  
  5. IF_END:  
  6. jmp END                 ; 跳转到多分支结构的结尾地址  
  7. ELSE_IF_BEGIN:      ; else if 语句块的起始地址  
  8. ; 可影响标志位的指令  
  9.         jxx ELSE_BEGIN      ; 跳转到else分支语句块的首地址  
  10. ……                  ; else if语句块内的执行代码  
  11. IF_ELSE_ END:               ; else if 结尾处  
  12.         jmp END         ; 跳转到多分支结构的结尾地址  
  13. ELSE_BEGIN:             ; else语句块的起始地址  
  14. ……                  ; else语句块内的执行代码  
  15. END:                    ; 多分支结构的结尾处  
  16. …… 
如果遇到这样的代码块,需要考察各跳转指令之间的关系。当每个条件跳转指令的跳转地址之前都紧跟JMP指令,并且它们跳转的地址值都一样时,可视为一个多分支结构。JMP指令指明了多分支结构的末尾,配合比较判断指令与条件跳转指令,可还原出各分支语句块的组成。如果某个分支语句块中没有判定类指令,但是存在语句块,且语句块的位置在多分支语句块范围内,可以判定其为else块。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇5.3 用if构成的多分支流程(2) 下一篇5.2 if…else…语句(2)

评论

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