首页> 中国专利> 一种通过静态分析测算代码指令最长运行时间的方法

一种通过静态分析测算代码指令最长运行时间的方法

摘要

一种通过静态分析测算代码指令最长运行时间的方法,首先解析待分析源代码对应的机器码指令序列,识别指令序列中分支指令的源地址和目标地址,得到指令的执行周期数。然后建立指令序列对应的有向无环图,按照有向无环图计算最长路径的方法,计算最长执行周期数,进而得到最长运行时间。如果建立有向无环图遍历过程中有向后跳转指令,则建立的是有向有环图,而且环还是有次数的,次数就是源代码中对应的循环次数,通过确定循环对应的循环体和循环次数,能够消除循环把有向有环图变成有向无环图,进而得到代码指令的最长运行时间。

著录项

  • 公开/公告号CN104407968A

    专利类型发明专利

  • 公开/公告日2015-03-11

    原文格式PDF

  • 申请/专利权人 北京控制工程研究所;

    申请/专利号CN201410601684.0

  • 申请日2014-10-30

  • 分类号G06F11/36;

  • 代理机构中国航天科技专利中心;

  • 代理人陈鹏

  • 地址 100080 北京市海淀区北京2729信箱

  • 入库时间 2023-12-17 04:31:51

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2017-06-13

    授权

    授权

  • 2015-04-08

    实质审查的生效 IPC(主分类):G06F11/36 申请日:20141030

    实质审查的生效

  • 2015-03-11

    公开

    公开

说明书

技术领域

本发明涉及一种基于静态分析代码对应的机器码指令序列来测算软件代码 最长运行时间的方法,特别是一种航天嵌入式软件的最长执运行时间测算方法, 属于技术嵌入式软件可靠性分析验证领域。

背景技术

实时系统要求的确定性决定了软件运行时间是实时系统的核心指标,尤其 对于航天嵌入式实时软件而言,软件运行时间影响到整星(器、船)的系统时 序,是系统及软件时序设计的关键,尤其在一些通讯、数据交换和中断服务程 序等场合,软件运行时间有严格的约束要求,软件设计如何满足时间要求有时 是一件比较困难的工作。

目前软件代码的运行时间测量主要依赖动态执行代码来获得,一般有两种 方式,一种是通过修改软件,插入特定代码,比如输出硬件信号在示波器上捕 捉软件中输出的信号来测试得到,或者记录处理器的地址线和数据线上插入标 志的时标来统计得到。另一种是在虚拟仿真硬件环境中,通过统计执行过的指 令来获取运行时间。

这些依赖动态执行代码来获得运行时间的方法,都需要外部的工具,修改 代码改变了原有时序特性,记录总线时标或依赖虚拟仿真硬件环境的方式成本 比较高。通过测量发现性能不满设计要求时,需要调整算法或者优化软件,并 再次测试,效率比较低。

通过不执行软件代码也可以很好的解决这个问题。比如《软件学报》第14 卷第1期发表的“程序执行时间的静态预估与可视化分析方法”中,提到基于 源代码的程序运行时间的可视化分析方法,通过分析源代码的控制流程图,建 立源代码与对应机器码之间的关联从而得到源代码执行的指令周期数,基于源 代码程序结构建立二叉树结构,依此来计算源代码的运行时间。

然而,这种方法存在一个问题,源代码编译有优化选项时,源代码的程序 结构与机器码的程序结构并不是一一对应的,这种方法不适用于航天嵌入式软 件。

发明内容

本发明解决的技术问题是:针对航天器上用的SPARC体系结构处理器和 ANSI C编程语言的问题,提供了一种不需要动态执行代码,通过静态分析指令 序列的控制结构,来建立有向无环图,用指令的执行周期数作为权值,从而计 算出最长运行时间的方法。

本发明的技术解决方案是:一种通过静态分析测算代码指令最长运行时间 的方法,包括如下步骤:

(1)设置SPARC体系结构中源代码对应的指令序列中每条指令的初始信 息;所述指令的内容包括序号、执行周期数、源地址和目标地址,序号代表每 条指令在指令序列中从0开始的整数编号,执行周期数代表指令执行需要的计 算机处理器周期数、源地址代表跳转到本指令的指令的序号集合、目标地址代 表本指令将要跳转执行的指令的序号,其中执行周期数初始值为0,源地址和 目标地址初始值为-1;

(2)逐条解析指令序列中的每条指令,如果是分支指令,则将本条指令的 目标地址记为本分支指令将要跳转执行的指令序号,同时本分支指令将要跳转 执行的指令的源地址添加本分支指令序号;如果不是分支指令,则本条指令的 目标地址和源地址不变;

(3)从指令序列的第一条指令开始逐条判断指令的序号与本指令目标地址 的大小,如果某条指令的目标地址不为-1且序号大于目标地址,则判定该指令 是向后跳转指令,将该指令作为起始指令,以该指令目标地址指令为终点截取 的一段指令序列作为待分析指令序列,并转到步骤(4);如果某条指令的序号 小于目标地址,则判定该指令是顺序或向前跳转指令,继续解析指令序列中的 下一条指令;

(4)分析待分析指令序列,提取其没有向后跳转指令的指令序列子集,查 询SPARCV8指令集手册获得指令序列子集中各指令对应的执行周期数数值, 将指令序列子集中的每条指令作为有向图中的一个点,在有顺序关系的前后指 令之间,以及向前跳转指令的源地址和目标地址之间建立有向线,权值为有向 线起始点指令的执行周期数,建立有向无环图,根据有向无环图计算最长执行 周期数,最长执行周期数与每个指令执行周期对应的绝对时间相乘得到最长运 行时间;所述每个指令执行周期对应的绝对时间由计算机处理器的频率确定;

(5)以当前向后跳转指令为起点,以原指令序列第一条指令为终点,逆序 分析原指令序列,解析第一个出现的产生SPARC体系结构条件码的指令,得 到两个操作数,将在后续的逆序分析中有自加、自减运算的操作数作为循环变 量,将在后续的逆序分析中只有赋值操作的操作数作为代表循环次数的操作数, 当代表循环次数的操作数是常值时,该常值记为循环次数,当代表循环次数的 操作数是操作地址或者从寄存器得到的值时,则分析当前向后跳转指令对应的 调用函数,分析调用函数的循环变量,循环变量对应物理参数的取值范围的最 大值作为循环次数;获得循环次数后,与步骤(4)得到的指令序列子集的最长 运行时间相乘得到待分析指令序列的最长运行时间,并将待分析指令序列的最 长运行时间赋值给当前向后跳转指令的执行周期数,将待分析指令序列与指令 序列中其余指令的跳转关系赋予当前向后跳转指令据此更新当前向后跳转指令 的源地址和目标地址;

(6)用赋值后的当前向后跳转指令替代原指令序列中的待分析指令序列;

(7)将替代后的指令序列作为新的原指令序列,重复步骤(3)~步骤(6) 直至新的原指令序列没有向后跳转指令后转入步骤(8);

(8)查询SPARCV8指令集手册获得新的原指令序列中各指令对应的执 行周期数数值,并分别赋予各个指令,将指令序列中的每条指令作为有向图中 的一个点,在有顺序关系的前后指令之间,以及向前跳转指令的源地址和目标 地址之间建立有向线,权值为有向线起始点指令的执行周期数,建立有向无环 图,根据有向无环图计算最长执行周期数,最长执行周期数与每个指令周期对 应的绝对时间相乘得到代码指令最长运行时间;所述每个指令执行周期对应的 绝对时间由计算机处理器的频率确定。

本发明与现有技术相比的优点在于:

(1)与依靠动态执行的方法相比,本方法不需要执行代码,通过静态分析 指令序列,就可以计算出最长路径上指令的周期数,使星载嵌入式软件时序验 证可以提前开展,而且性能测定的方法相比现有的动态测试的方法更有效、更 高效;

(2)与“程序执行时间的静态预估与可视化分析方法”相比,本方法直接 对二进制机器码进行静态分析,不依赖于源代码和编译优化选项,适用性更强。

附图说明

图1为本发明方法向前和向后跳转示意图;

图2为本发明方法指令序列结构图;

图3为本发明方法一次消除循环示意图。

具体实施方式

结构化编程语言如C语言的源代码,语句结构有顺序、分支和循环三种, SPARC体系结构语言编译后,指令序列有以下几个特点:

(1)指令序列只有顺序和分支两种语句结构,分支包括向前跳转和向后跳 转,如图1;向前跳转对应C语言中的if-else和switch两种分支结构,向后跳 转对应C语言中的for、while和do-while三种循环结构,一次循环的机器码指 令序列如图2;

(2)向前跳转和向后跳转这两种语句结构可以有包含关系,但不会有交叉。 也就是说,向前跳转和向后跳转这两种指令的跳转开始(源地址)和跳转结束 (目标地址)这个范围内可以包含其他的跳转指令,但不允许跳转到其他跳转 语句的开始和结束范围内。也就是说,先开始的跳转后结束,而后开始的跳转 先结束;其中,跳转指令本身的地址称为源地址,跳转指令中解析出的待跳转 去的地址称为目标地址。

(3)向后跳转对应的是源代码中的循环结构,会执行多次,对一个具体函 数来说循环次数是个常数或是个变量。常数就是常值或全局常量,变量就是全 局变量、虚参或者函数内的临时计算值,考虑航天器软件可靠性设计措施,对 于循环次数不确定的情况,比如临时计算值作为循环次数,要求增加最大循环 次数的保护,避免异常情况下不确定的循环次数或死循环,因此循环次数的上 限一般都是可预先确定的;

(4)一条分支指令只有一个目标地址,但任意一条指令可能会有多条源地 址,也就是说一条分支指令只能去一个地址,但任意一条指令可能会有多条分 支指令的目标地址指过来;

(5)一个函数的指令序列一般只有一个入口,一个出口,但有jmpl指令 时,会提前退出。

基于上述SPARC体系结构处理器上C语言编译后指令序列的特点,通过 静态分析机器码指令序列的控制结构,建立起有向图,指令的执行周期数作为 权值,如果没有向后跳转指令,有向图就是无环图,有向无环图的最长路径解 算有成熟的方法。

如果有向后跳转指令,有向图就是有环图,为了简化计算,就要消除环, 把有向有环图变成有向无环图。有环的地方就是循环,其实就是循环体执行了 多次而已。循环体本身可能还包含循环体,但采用递归的方法,最里面的循环 体就是简单的顺序和向前跳转两种语句结构,因此只要确定了循环体和循环次 数,就可以实现把有向有环图变成有向无环图。

1、指令序列预处理

对待分析的SPARC体系结构源代码对应的机器码指令序列进行指令格式 解析,识别分支指令的源地址和目标地址,获取每条指令的相关信息。

(1.1)设置每条指令的初始信息

整个指令序列称为IS,其中每条指令具有以下信息:序号offset、执行周 期数cycle、一组源地址addrFrom,一个目标地址addrTo。如下所示为一次循 环的源代码和对应的机器码指令序列,图2为指令序列结构图。

后续分析中用指令序号作为每条指令的相对地址,序号有效值是从0的整 数,无效序号用-1表示。序号为offset的指令的真实地址为addr=ADDR0+offset ×4,ADDR0为第一条指令的真实地址。

每条指令的offset就是当前指令的序号,cycle置初值为0,源地址和目标 地址初始值置为无效序号-1;

(1.2)建立指令与执行周期数之间的查询表(后续简称指令周期表),指 令的执行周期数可在指令集手册中查到,其中执行周期数代表指令执行需要的 计算机处理器周期数;所述指令集手册是SPARCV8指令集手册;

(1.3)对指令序列中逐条进行指令格式解析,查询指令周期表得到指令的 执行周期数cycle;如果是分支指令,本条指令的信息中记录目标地址addrTo, 值为本分支指令待跳转去的指令的序号,同时本分支指令待跳转去的指令的信 息中记录源地址addrFrom[i],值为本分支指令的序号,i表示源地址的个数, 从0开始累加;如果是顺序指令,则本条指令目标地址和源地址保持不变。

2、建立有向无环图

在步骤1的预处理结果的基础上,建立指令序列结构对应的有向无环图。

(2.1)判断是否有向后跳转指令,向后跳转指令即源代码中的循环语句;

逐条指令判断当前指令的序号offset与当前指令目标地址addrTo的大小, 如果addrTo有效且offset大于addrTo,则说明当前指令是向后跳转指令,否 则为顺序或向前跳转指令;

(2.2)遍历整个指令序列,如果没有向后跳转指令,说明整个指令序列由 顺序或向前跳转指令组成,则可以转到步骤(2.3)建立有向无环图,否则转到 步骤3消除循环;

(2.3)以一条指令作为有向图中的一个点,在有顺序关系的前后指令之间 (源地址和目标地址为-1),以及跳转指令的源地址和目标地址之间建立有向 线,权值为有向线起始点指令的执行周期数,建立有向无环图,按照有向无环 图计算最长路径的方法,计算出最长执行周期数NP,根据处理器设置的频率 可以得到每个指令的执行周期对应的绝对时间DT,则最长运行时间T=NP× DT。

3、消除循环

如果步骤2建立有向无环图(2.2)中遍历过程中发现有向后跳转指令,则 说明源代码中有循环,如果以步骤2建立有向无环图(2.3)中的方法建立的有 向图是有向有环图,而且环还是有次数的,次数就是源代码中对应的循环次数。 把有向有环图变成有向无环图,主要就是消除循环,消除循环主要是确定循环 体和循环次数,方法如下:

(3.1)如果当前指令为向后跳转指令,则以当前指令的序号offset为起点, 以目标地址指令的序号addrTo为终点,截取部分指令序列形成待分析指令序 列,在待分析指令序列的起点和终点之间遍历指令序列,分析提取生成一个指 令序列子集SUBIS,这个指令序列子集就是对应的循环体。把这个指令序列子 集按照步骤1和步骤2的方法进行处理,计算出最长路径。

(3.2)在指令序列IS中,以当前向后跳转指令为起点,以指令序列IS中 的第一条指令为终点,按执行序列实际执行的逆序来分析循环变量和循环次数。

分支指令基于条件码,SPARC体系结构中有Z、V、N、C四个条件码, 也就是说不同状态的条件码组合对应不同的分支指令,条件码由特定的指令执 行结果产生,在SPARC体系结构的指令中,以”CC”为后缀的指令就是产生 条件码的指令。

因此以当前向后跳转指令为起点,逆序分析过程中,最先出现的产生条件 码的指令就是源代码中循环变量与循环次数判断的语句。通过指令格式解析, 可以得到两个操作数OP1和OP2,其中一个是循环变量OPi,一个实循环次 数OPN。

按照以下的原则来识别循环变量,确定循环次数:继续逆序分析,如果OP1 或OP2有自加、自减等运算,一般情况下该操作数就是循环变量OPi;如果 OP1或OP2只有赋值操作,一般情况下该操作数就是循环次数OPN。其中操 作数,是计算机指令中的一个组成部分,它规定了指令值中进行数学运算的量。 操作数指出指令执行所需要的数据的来源,是汇编语言指令序列中的一个字段, 这个字段可以存放操作数本身,可以放操作地址,也可以存放操作地址的计算 方法。

如果逆序分析完后,循环次数OPN是常值,则循环次数OPN就是该值; 如果循环次数OPN是从一个操作地址获取的值,则说明该循环次数是全局变 量,如果从%i0-%i5六个寄存器或%o0-%o5六个寄存器得到,说明该循环次数 作为虚参传入,循环次数不是常值的情况需要人工分析源代码及其机器码指令 序列,则分析当前向后跳转指令对应的调用函数,分析调用函数的循环变量, 循环变量对应物理参数的取值范围的最大值作为循环次数。

SPARC体系结构中,叶子函数就是用调用函数的寄存器窗口的函数,没 有调用函数的函数一般是叶子函数;非叶子函数是相对于叶子函数而言的,使 用新的寄存器窗口,一般要调用其他函数。对叶子函数而言,输入参数通过 %o0-%o5传入,对非叶子函数而言参数通过%i0-%i5传入。

4、去除循环后,将待分析指令序列的最长运行时间赋值给当前向后跳转指 令的执行周期数,将待分析指令序列与指令序列中其余指令的跳转关系赋予当 前向后跳转指令并更新当前向后跳转指令的源地址和目标地址,然后用赋值后 的当前向后跳转指令替代指令序列中的待分析指令序列,形成替代后的指令序 列。如图3所示,遍历过程到指令08时,识别指令08为向后跳转指令,指令 03是其向后跳转的目标指令,因此指令03至指令08为待分析指令序列,计算 该待分析指令的最长运行时间,并将该最长运行时间赋给当前向后跳转指令 08,将待分析指令序列与指令序列中其余指令的跳转关系赋予当前向后跳转指 令,用08′代表赋值之后当前向后跳转指令并更新其源地址和目标地址,最后 用赋值后的当前向后跳转指令08′替代指令序列中的待分析指令序列指令03至 指令08,形成替代后的指令序列。

5、消除循环后,继续遍历替代后的指令序列,如果遍历过程中发现有向后 跳转指令,多次重复步骤3、步骤4,直至得到没有向后跳转指令的指令序列, 按照步骤2建立有相无环图,计算最长运行时间。

6、特殊情况

大多数情况下,一个函数的指令序列一般只有一个入口、一个出口,所以 在遍历指令的之后,就是从入口指令开始,到出口指令结束。但极少数的特殊 情况下,有jmpl指令时,会提前退出函数,即有一个入口,多个出口,出口指 令的判断就不仅仅是最后一条指令,jmpl指令后下一条指令也是退出函数指 令。

本方法中虽然不动态执行指令序列,但为了分析出循环次数,需要模拟动 态执行过程,模拟动态执行过程就是通过寄存器窗口和内存等上下文信息来分 析具体的循环变量以及循环次数。循环次数如果不是常值,则分析当前向后跳 转指令对应的调用函数,分析调用函数的循环变量,循环变量对应物理参数的 取值范围的最大值作为循环次数。

本发明说明书中未作详细描述的内容属本领域技术人员的公知技术。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号