程序与自动机及静态分析杂想

不知道在胡乱讲些什么东西,垃圾内容,勿看

引子

有限状态自动机就是一些操作作用在状态上,导致状态和状态迁移的过程。程序运行就是用户向计算机输入信息并经过一系列的计算并从中获取结果信息的一个过程。而静态分析就是不实际执行程序通过初始状态模拟执行得到最终状态的过程。但是有限状态自动机,程序执行及静态分析之间有什么联系呢?

更新:读了《计算的本质:深入剖析程序和计算机》这本书,才知道下面的思想这本书里都有详细而有系统的探讨过


有限状态自动机与程序执行

  • 计算机内存与寄存器
  • 函数执行
  • 图灵机
  • 基于概率的自动机

计算机内存与寄存器

程序在计算机中执行时是以进程的角色存在的。进程包括代码,数据以及描述进程执行情况的状态信息。这种状态信息是狭义的,进程的状态其实可以通过当前进程所对应的计算机内存和寄存器来唯一标识。

当你企图使用计算机解决一个问题时,其实就是在思考如何将这个问题表达成状态(用哪些变量存储哪些数据)以及如何在状态中转移(怎样根据一些变量计算出另一些变量)。所谓的空间复杂度就是为了支持你的计算所必需存储的状态最多有多少,所谓时间复杂度就是从初始状态到最终状态中间需要多少步。— [王勐-知乎]

进程的执行就相当于当前计算机所处的状态集迁移到另一状态集的过程。程序由函数组成,函数由语句组成,函数以及函数中语句在经过编译后是以相应的汇编指令存在的。一个程序的执行可以描述成函数作用于计算机,使其从一个状态集合迁移到另一个状态集的过程,更细一点描述的话也可以说是语句作用于计算机。但是归根到底,程序在计算机中的执行都是通过一条条的汇编指令作用于计算机来完成的。
程序与自动机及静态分析杂想_第1张图片
一个具体体系结构的汇编指令种类是一定的。汇编指令可以对应到数学上的函数f(x),其中函数的定义域和值域都相同,都是计算机内存和寄存器的状态集合。那么一个程序的执行可以描述成*f(x)*g(x)h(x)… ,就是汇编指令对应函数的一个有限排列。

这种有限排列和“字符串”排列不同,字符串的相似程度可以通过编辑距离来测量,但是汇编指令的相似程度可不能通过简简单单的编辑距离来测量。汇编指令串中包含了控制跳转信息,而字符串是顺序单线的模式。汇编指令串通过CFG(程序控制流图)+ 编辑距离能够更好地描述程序的相似程度。

其中前一个函数的输出作为后一个函数的输入,初始的输入值是计算机的初始化状态,当然这个初始状态也可以通过人为设定, 例如计算10!的时候,初始值就是10。经过一系列的运算得到计算机的结束状态集,人们再从这种结束状态集中获取想要的信息。从汇编指令这个角度来看,程序的运行和创建有限状态机的过程很相似。
程序与自动机及静态分析杂想_第2张图片

函数执行

前面提到,程序的执行就是计算机状态迁移的过程。计算机状态迁移粒度可大可小,可以以函数为单位,也可以以语句或者汇编指令为单位。有人会提出疑问,函数调用前和调用后栈上的状态不是没有变化,当前callee的栈帧被刷掉以后,caller及其之前的栈帧信息不是没有变化吗?这种理解其实没有真正理解我们所说计算机状态迁移的概念,我们所说的状态不止包括栈,还包括堆等内存空间。所以即使栈上的信息没有变化,堆或者寄存器的状态信息也有可能会变化。

有人会说我可以写出一种没有改变任何状态的函数,但是试问这种函数又有什么作用呢?函数影响外界就三种方式,指针或引用传参,修改全局变量或者堆上数据,还有返回值。如果一个函数没有采用以上任何一种方式,这种函数就单单只是空耗CPU,不会产出任何有价值的东西。

其实对上面的函数调用的方式进行延伸,就会发现函数调用过程,其实就是栈的一个动态的伸缩过程。这种伸缩过程既可以通过图方式来展示,可以通过树的方式来展示。

程序与自动机及静态分析杂想_第3张图片

用树形结构来展示上述过程如下所示:

程序与自动机及静态分析杂想_第4张图片

图灵机

A Turing machine is an abstract “machine”[1] that manipulates symbols on a strip of tape according to a table of rules; to be more exact, it is a mathematical model that defines such a device.—— [维基百科]

图灵机是一种抽象的计算模型,是模拟的人们的思考验算过程。验算纸对应着图灵机的纸带,人的大脑对应着图灵机的控制器和程序存储器,人们可以根据验算过程在纸张上进行数据填写修改以及删除。图灵机使人们的注意力从设计复杂的机器转移到设计计算过程,然后使用这种通用的机器来进行计算。

程序与自动机及静态分析杂想_第5张图片

经过上面的描述,可以发现程序运行修改计算机的状态和图灵机的运算过程相同。这不白说吗,现代计算机就是按照图灵机为原型来设计的,只是冯诺依曼将这种虚拟的机器向现实中的机器更近了一步,提出了程序以及数据的存储方式,并且将图灵机计算的数学观念转化到语言指令上来。

基于概率的有限状态自动机

前面已经提到过程序作用在计算机上,使计算机状态迁移的过程可以使用有限状态自动机来刻画。但是程序执行的过程中有些指令的执行是有条件的,也就是存在概率的,比如说条件跳转指令后面的指令的执行就是有概率的。最经典的例子就是循环分支指令后面的指令执行的可能性较大。

但需要注意的是,这种概率是不定的并且数据相关的,并不具有研究价值,研究jmp dst后面执行mov ebp, ecp 的概率是多少没有什么意义。但是CPU做这些就比较得心应手了,因为CPU处于当前程序中,得到跳转的概率情况虽然对所有的程序不具有普适性,但是在当前这程序运行环境中是有很大意义的,因为条件跳转指令会造成流水线的阻塞,会严重影响效率。CPU的分支预测部件就是专门设计用来进行分支预测的,对程序的执行效率有显著的提升。

但是当基于概率的有限状态自动机中的概率是固定的时候,就变得简单并有意思起来了。吴军老师在其所著的《数学之美》中就提到使用基于概率的有限状态机来进行地址的识别。有限状态自动机最早的应用是用于程序语言语法上,由于语言语法是不能容忍错误的,但是有些场景需要模糊匹配。其实编译器也可以吸取基于概率的有限状态机的思想,用来进行纠错或者指导程序员的编写,例如代码自动补全。


你可能感兴趣的:(计算机杂想)