Compilation x86中的基本块和控制流
红龙书包含第529页的算法9.1和将汇编代码划分为基本块的算法。该算法基本上是: 输入:汇编,作为说明列表。Compilation x86中的基本块和控制流,compilation,x86,code-analysis,Compilation,X86,Code Analysis,红龙书包含第529页的算法9.1和将汇编代码划分为基本块的算法。该算法基本上是: 输入:汇编,作为说明列表。 输出:基本指令块的列表 第一阶段:标记领导者。(程序的)第一句话是引导语。分支目标的任何语句都是leader。任何紧跟在分支后面的语句都是前导 阶段2:组装模块。要生成基本块,请将引线和所有语句添加到块中,直到遇到另一个引线。这样做,直到没有语句留下 结束并返回块 随后,他们使用该区块结构进行控制流分析。开发的基本结构是控制流图;它是通过将基本块视为图形中的节点来实现的,如果Bi以跳到B
输出:基本指令块的列表 第一阶段:标记领导者。(程序的)第一句话是引导语。分支目标的任何语句都是leader。任何紧跟在分支后面的语句都是前导 阶段2:组装模块。要生成基本块,请将引线和所有语句添加到块中,直到遇到另一个引线。这样做,直到没有语句留下 结束并返回块 随后,他们使用该区块结构进行控制流分析。开发的基本结构是控制流图;它是通过将基本块视为图形中的节点来实现的,如果Bi以跳到Bj的方式结束,则创建从块Bi到Bj的有向边 Cooper、Harvey和Waterman(在从调度代码构建控制流图时)指出,如果存在到内存地址或寄存器中保存的位置的跳转,那么创建控制流图的这种算法是不够的
这带来了几个问题。程序集何时可以包含指向内存中某个位置的分支?什么是计划代码?从x86构建控制流图时,是否还有其他问题需要注意?直接从x86构建控制流图的最著名的算法/实现是什么?在一些情况下,对寄存器的内容(或变量内容)执行分支
这与操作系统调度无关,它是一种提高性能的编译器技术,对CFG有影响。阅读-谢谢你的评论。我只是把问题重新写了一遍,让它更清楚。你的评论仍然有效。但我不明白:在重新排列指令之后,我仍然有x86代码。因此,CFG可能与原来的有所不同,但我不明白为什么在调度发生后构建CFG会使算法有所不同。感谢您提供了一个很好的示例。深入挖掘之后,发现直接从程序集生成CFG是相当棘手的,因为像您指出的那样存在间接跳转。似乎最好的方法就是进行某种模拟。这是静态反汇编程序的问题之一,这使得交互式反汇编程序,如IDA,功能强大。。。
int fptr_call( int (*ptr)(int) ) {
return (*ptr)( 3 );
}
_fptr_call:
0000000100000e70 pushq %rbp
0000000100000e71 movq %rsp, %rbp
0000000100000e74 subq $0x10, %rsp
0000000100000e78 movl $0x3, %eax
0000000100000e7d movq %rdi, 0xfffffffffffffff8(%rbp)
0000000100000e81 movl %eax, %edi
; Call based on %rbp, copied from %rdi which is ptr
0000000100000e83 callq *0xfffffffffffffff8(%rbp)
0000000100000e86 addq $0x10, %rsp
0000000100000e8a popq %rbp
0000000100000e8b ret
0000000100000e8c nopl (%rax)