源代码的结构在编译器中往往会在某个环节被转换成CFG,不同的控制语句会生成形形色色的控制流结构,而在后端转换的过程中又会生成许多前端语法无法描述的结构出来,在控制流分析的过程中需要去识别这些结构。这篇文章简单的介绍一些基本结构。

1,基本块(basic block)。基本块是一个执行时连续的语句序列,往往最后会跟一个终结语句,比如跳转,条件跳转或者返回,除了最后一个语句外没有任何的分支或跳转命令。


流图的分类与识别

基本块

2,分支结构(branch)。分支结构由一个条件基本块和两个分支基本块组成,一般语言中的if\while\for都会产生这种结构。

流图的分类与识别

分支结构

根据分支结构的上下文,又可以区分为if-then结构,if-else结构和if-then-else结构。


流图的分类与识别
if-else结构
流图的分类与识别
if-then结构
流图的分类与识别
if-than-else结构

分支结构除了常见的二路分支外,还有n路分支(n>=3),由switch的语义产生,不过很少见到硬件指令集中支持它,往往都是IR指令集中支持。

3,循环结构(loop)。循环结构是一个非常重要的结构。如果在CFG的深度优先生成树(DFST)中有一条指向其祖先的边m->n,则m和n之间的子图构成了一个循环,n被称为循环头部。


流图的分类与识别
循环结构

其中B2被称作循环头,而E1则是DFST中的反向边。

根据循环出口的所在,还可以进一步区分为while循环和do-while循环:


流图的分类与识别
do-while结构
流图的分类与识别
while结构

一般情况下,循环结构只会有一个入口,程序中所有的其他结构想要进入这个循环只能通过这个入口进入,但极少的情况下也会有多个入口:

流图的分类与识别
不可规约循环

上图中,B3和B4都是循环的入口。

如果流图中的所有循环都只有一个入口,则称为可规约流图(reducible),否则就称为不可规约流图(inreducible)。不可规约流图在常规程序中很难见到,但在优化后的程序中可能会频繁出现。

往往不可规约流图中都会有这样一个基本子结构:


流图的分类与识别

不可规约子结构

参考资料:

1,《高级编译器设计与实现》

2,反编译技术与软件逆向分析。

相关文章:

  • 2021-11-20
  • 2021-09-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-10
  • 2021-10-06
猜你喜欢
  • 2022-12-23
  • 2021-06-13
  • 2021-11-19
  • 2022-12-23
  • 2021-08-30
  • 2021-07-18
  • 2021-07-10
相关资源
相似解决方案