APP下载

X86汇编程序可视调试虚拟机的设计与实现

2012-07-25吴伟民刘沛昌

计算机工程与设计 2012年7期
关键词:断点寄存器流程图

苏 庆,吴伟民,黄 彪,刘沛昌,刘 聪

(广东工业大学 计算机学院,广东 广州510006)

0 引 言

程序可视化[1]作为科学计算可视化[2]的一个重要分支,其主要特点体现于编程以及运行环境可视化两个方面[3]。目前,汇编语言编程在单片机应用研发以及底层硬件驱动程序设计[4]开发等方面仍然存在普遍应用。然而大多数汇编语言可视化编程开发工具仅局限于程序编辑可视化层次,并无将汇编语言的执行过程进行可视化呈现[5],使得用户未能深入观察程序的执行过程,大大影响了汇编程序的开发以及调试效率[6]。

由此,本文应用虚拟机设计理论[7]以及可视化技术相结合,设计并实现一个可视化汇编程序集成开发环境——X86VVM2[8],该环境具备从汇编程序编辑到程序动态调试各阶段进行全面可视化的特征。

1 X86VVM2内核

作为可视化汇编程序集成开发环境的一个重要组成部分,X86VVM2虚拟机内核对X86汇编源程序进行词法分析、语法分析、异常处理等处理过程,将源程序翻译成可被X86VVM2内核执行的机器码指令。X86VVM2内核主要有如下4个主要功能:

(1)仿真实现X86汇编指令功能:包括汇编语言指令集的语义实现。

(2)解释执行X86汇编指令:执行X86汇编指令流。

(3)异常处理:对词法分析、语法分析及执行过程中遇到的异常进行处理。为方便程序设计者准确而快速地定位程序的错误,X86VVM2将各个阶段出现异常或错误所对应的源代码行号直接反馈给用户。

(4)可视化接口:按照模块化的开发思想,对内核进行类封装,并为可视化层提供接口,方便可视化层对X86汇编语言执行过程可视化。

X86VVM2是一个采用寄存器处理器架构的可视化汇编程序集成开发环境。该环境在内核内置堆栈,堆栈操作指令及函数的调用直接依靠此堆栈,从而提高内核处理速度,同时降低数据处理时候的难度。X86VVM2内核架构如图1所示。

图1 X86VVM2内核架构

汇编器对X86汇编程序进行汇编;虚拟内存存放汇编过后可被虚拟机执行的机器码;栈中存放执行push、pop等堆栈操作指令及call指令后的数据;虚拟CPU执行虚拟内存中的机器码序列;符号表为机器码生成、异常处理模块及数据可视化提供原始信息。

X86VVM2首先将预编辑完毕的源程序存放到内存的指定空间,经词法分析,语法分析等关键步骤,设置执行程序的起始地址。虚拟机从起始地址开始执行源程序。虚拟机解释执行一条指令时,可能需要进行如下4个动作:

(1)取指 (Fetch):根据当前pc寄存器值取出虚拟内存中所对应的指令;

(2)译码 (Translate):识别当前指令的操作数;

(3)分派 (Dispatch):执行此条指令。

(4)停机 (Halt):当遇到停机指令或者程序出错时,虚拟机停止解释执行汇编程序。

2 X86VVM2可视化

基于Bednarik[9]等人提出的程序可视化流程及前人对程序可视化的研究,视X86VVM2内核的相关数据为可视化的原始数据,通过相应的可视化算法,将虚拟CPU寄存器值的变化及寄存器之间数据的交互、程序编辑、内核栈中数据的动态变化及调试过程进行可视化。

程序执行时,通过内核封装的可视化接口,跟踪内核执行的可视数据的变化,动态的反映在可视化界面中,从而实现源程序执行过程的可视化。X86VVM2可视化功能主要包含如下几个部分:

(1)CPU可视化:实现内核CPU内寄存器值的变化及寄存器之间数据交互的可视化。对于X86汇编语言,必须实现CPU寄存器的数据实时变化情况,包括各种通用寄存器、变址寄存器、堆栈寄存器、段寄存器、指令指针寄存器以及状态标志寄存器等。

(2)栈信息可视化:实现内核栈中内容的动态变换。X86汇编语言是基于栈式计算机模型定义,所以栈信息的实时显示非常重要。

(3)数据信息可视化:显示源程序中用户自定义的逻辑段、变量、标识符、子程序名称以及函数的属性。

(4)编辑可视化:向用户提供程序代码编辑交互界面,同时支持语法着色。同时,X86VVM2编辑可视化界面还支持断点的动态设置。程序设计者只需要通过点击编辑窗口最左边的灰色框,即可在当前点击的位置设置断点。

(5)调试可视化:通过可视化的人机交互设计,实现调试行为可视化。

X86VVM2整体执行效果如图2所示。图中从左至右分别依次为CPU可视化窗口、堆栈信息显示窗口、数据显示窗口及编辑可视化窗口。可视界面中下面是信息显示窗口,用于显示程序异常提示信息及程序运行的结果。

2.1 程序编辑可视化

X86VVM2采用类似于主流高级语言集成开发环境类似的着色方案,具有较高的用户亲和度。X86VVM2编辑可视化功能包括:语法着色、行号显示及断点设置:

(1)语法着色。为方便程序设计者编辑程序,X86VVM2对不同的单词类型进行语法高亮显示。该着色方案以不同类型颜色值的十六机制表示形式区分各类单词。其中关键字为0xFF00FF (棕色);常量为0x0000FF (黑色);伪码为0x123456(粉红色);注释为0x00FF00(绿色);寄存器为0x00FF00(宝蓝色)。

(2)行号显示。X86VVM2直接将行号信息显示在编辑可视化界面中。同时内核运行时,根据当前运行的指令定位代码编辑框内的指令,从而实现代码跟踪可视化。

(3)断点设置。断点功能是程序开发环境必须具备的基本程序调试功能。当程序运行过程中遇到断点时,内核首先获取当前设置断点的行号信息,实现X86VVM2动态调试。

X86VVM2的编辑可视化窗口如图3所示。X86VVM2对关键字、数字及注释等进行语法着色,同时在最左边显示当前源代码对应的行号,方便了程序设计者对源代码的阅读,同时在图中第20行和第27行出现的白色圆圈表示在当前行设置断点,图中显示的是向内核发出连续执行命令时,程序运行暂停在第一个断点,此时编辑框内第20行的程序内容被突出显示。

图2 X86VVM2集成开发环境界面

图3 X86VVM2编辑可视化

2.2 CPU可视化

汇编程序具有直接访问CPU寄存器的特点。X86VVM2的CPU信息可视化重点关注CPU内部寄存器数据的变化及寄存器之间数据交互的动态可视化。寄存器数据的变化通过寄存器值红色高亮的表现形式进行体现;寄存器之间数据的交互按照CPU内寄存器在可视化界的布局,用红色箭头来表示数据交互的方向性。同时X86VVM2还将内核当前执行的指令显示在CPU可视化窗口中。

X86VVM2CPU信息可视化运行过程如图4所示。中间蓝色的竖线模拟表示系统数据总线,寄存器之间的数据交互就通过此线。图中的两个红色箭头表示数据传递的方向,最下方的内容表示当前运行的指令 (在实际运行时,该指令是红色字体标示)。对指令进行分析可知,可视化界面箭头所表示的数据传递的方向正确。

图4 CPU可视化效果

2.3 栈信息可视化

标准X86汇编语言中,当遇到堆栈操作指令或函数调用指令时,栈中数据会发生变化,因此,将栈中数据及数据的变化进行可视化,方便程序设计者对汇编程序的调试。

图5是某个程序运行过程中X86VVM2栈信息可视化截图。栈顶的位置随着程序找涉及堆栈操作指令及函数调用指令所引起的栈中数据变化而变化,从而实现栈的动态可视化。

2.4 程序调试可视化

调试可视化作为X86VVM2实现X86汇编语言执行过程可视化中一个重要的模块,程序设计者可以通过菜单或点击工具按钮的方式向内核传递调试的动作。图6展示的是X86VVM2的调试可视化接口。

X86VVM2采用指令中断形式,程序设计者可以在编辑可视化界面设置断点,内核根据断点设置的情况中断指令的运行。X86VVM2支持单步调试和连续调试两种调试方式。调试过程中,根据当前运行指令的行号来判断是否当前行号是否在断点数组中,如果存在则暂停指令的运行,如果不存在,则连续运行虚拟内存中的指令。调试程序时,通过获取存放在虚拟内存中指令的行号信息,动态定位编辑框中的内容,实现调试过程中代码跟踪可视化。

程序流程反映程序员的设计思路,所以无论是对程序流程作静态可视化还是动态可视化,都可以起到协助程序员对设计思路的逐步形成以及求精、优化的重要作用。其中程序流程静态可视化可以为程序员优化设计算法提供辅助;而程序流程动态可视化则可以迅速定位至程序热点区域,以及该热点区域在设计思路中的逻辑位置,对提高程序效率具有重要意义。

程序流程可视化[10]同时还为程序的调试和进一步理解提供了一种重要的辅助手段。流程图的自动生成无疑给程序编写人员带来了很大的便利。根据X86汇编语言的特点,为了更好地展示汇编函数调用的动作,X86VVM2实现了一个具有翻页效果的流程图,其实现过程分为以下3个步骤:

(1)基本块划分及建立链表。将源程序划分为各个逻辑上独立的模块,并在内核建立其相关数据结构,使基本块按顺序连接起来,形成一条静态链表。

(2)绘制主流程图及子流程。从模块链表中查找属于主程序的模块,并将其依次绘制于流程图显示界面;继而从模块链表中找出当前子函数所对应的模块,并显示在流程图显示界面中。

(3)分页效果实现,函数调用或用户点击子函数时,流程图界面显示子程序流程,子函数运行完时或用户点击主流程图时,流程图界面显示主程序流程图,实现流程图的动态切换,实现流程图的翻页。

2.4.1 模块划分及建立静态链表

按照汇编指令是否影响程序执行流程流程图,将汇编指令分为见表1的5种类型。

表1 汇编指令分类

通过遍历保存在虚拟内存中的指令,建立起模块静态链表。建立X86VVM2模块链表的算法描述如下:

(1)保存跳转指令 (包括条件跳转指令和无条件跳转指令)的行号及其跳转的地址 (即行号)。非函数调用其地址保存在m_addrList数组中,函数调用的地址保存在m_callArray数组中。

(2)对上述m_addrList和m_callArray数组中的内容去掉重复值,并按小到大排序。

(3)重新遍历虚拟内存中的指令数组,填充各个模块的信息,建立模块链表。由于X86VVM2将模块的5种类型都看作独立的基本块,因此m_addrList[i]和m_addrList[i+1]都当作一个模块进行处理,同时m_addrList[i]和m_addrList[i+1]之间的内容也当作一个模块。

例如对于下列汇编代码片段:

假设已经建立好指令数组。首先找出指令数组中jmp,call,jz指令所在的行号和跳转地址,分别为3、7、11和6、15、10。将这些地址去掉重复值后进行排序,结果为3,6,7,10,11,15。然后按照以排序好的数组将源程序分为多个模块,数组相邻两项之间的数子组成一个模块。如1—2,4—5,8—9,12—14。由于X86VVM2将每条跳转指令都作为单独的一个基本块处理,所以上述代码分为1—2,3,4—5,6,7,8—9,10,11,12—14,15共10个基本块。

2.4.2 流程图的绘制

流程图的绘制包括主流程图的绘制以及子流程图的绘制。

在流程图的绘制中,无条件转移指令、函数调用指令以及返回指令共享同一中无条件转移节点。流程图的绘制过程算法如下:

(1)绘制程序开始节点。

(2)绘制当前流程图页面确定的显示模块。

(3)如果入到子流程图的入口,则进入子流程图的绘制。

(4)绘制结束节点。

(5)绘制开始节点、结束节点及模块与模块之间的连接。

在X86VVM2运行过程中遇到函数调用时,流程图界面显示子程序流的流程图,子函数运行完时,流程图显示界面显示主函数流程图。X86VVM2的流程图翻页显示效果借助栈数据结构,其实现分为如下3个步骤:

(1)将当前页面绘制过程中保存的第一模块的首地址压栈 (push)。

(2)确定被调用的子函数。

(3)画出子程序流程图。

子程序调用返回时,将先出栈,然后画出以此栈顶节点开始的主程序流程图。

3 实验与分析

以一个十六进制形式向屏幕打印输出十进制数字的汇编程序print.asm为例,展示其代码流程图的可视化效果。

当程序设计者使用单步运行命令模式进行调试时,首先缺省显示print.asm主程序的流程图,如图7(a)所示。

实体粗线方框 (在实际运行过程中,该方框为较醒目的红色,易为方便用户识别)表示的模块指示当前运作的模块,当程序执行至第6行,即调用show_msg子函数时,则自动由主程序流程图切换至show_msg子函数的子程序流程图,如图7(b)所示。

由于X86VVM2的可视化流程图功能向用户提供不同粒度的可视化效果,令用户可在程序调试过程中实时在不同层次的流程图之间自由切换。

print.asm程序源代码如下:

图7 可视化流程图效果

4 结束语

本文应用虚拟机构建技术以及可视化技术构建的汇编程序集成开发环境X86VVM2具有将汇编程序开发各个阶段全面进行可视化,以辅助用户进行可视编程以及调试的特性。而程序调试过程可视则提供不同粒度程序流程图供程序设计者使用,并且与程序执行过程密切结合,实时对比当前程序执行指令在逻辑视图中的位置。

另一方面,X86VVM2采用自行开发的虚拟机内核,可对汇编程序代码片段直接解释执行,适用于软件逆向工程后反汇编结果的动态跟踪调试。

[1]LI Kai-lun,WU Wei-min,SU Qing.Analysis and implementation of visualization Java class loader [J].Computer Engineering and Design,2006,27 (20):3909-3912 (in Chinese).[黎凯伦,吴伟民,苏庆.可视化Java类装载器的分析与实现[J].计算机工程与设计,2006,27 (20):3909-3912.]

[2]Ben Fry.Visualizing Data.The United States:O’Reilly Media,Inc[S].2009:2-6.

[3]SU Qing.Research and realization for dynamic visualization technology of Java program and object relation [D].Guangzhou:Guangdong University of Technology,2006 (in Chinese).[苏庆.Java程序及对象关系的动态可视技术研究与实现 [D].广州:广东工业大学,2006.]

[4]Muhammad Ali Mazidi,Janice G Mazidi,Danny Causey.The 80x86IBM PC and compatible computers volumes I &&II assembly language,design,and interfacing [M].5th ed.TheUnited States:Prentice Hall,2009:54-57.

[5]LIAO Hua-yun.Research and realization for X86visual virtual machine[D].Guangzhou:Guangdong University of Technology,2005(in Chinese).[廖华赟.X86可视虚拟机的研究与实现 [D].广东广州:广东工业大学,2005.]

[6]SU Qing,WU Wei-min,LI Kai-lu.Design and realization of structural software automated test [J].Computer Engineering and Design,2006,27 (8):1417-1419 (in Chinese). [苏庆,吴伟民,黎凯伦.结构性自动软件测试的设计方法与实现[J].计算机工程与设计2006,27 (8):1417-1419.]

[7]Jim Smith,Ravi Nair.Virtual machines:Versatile platforms for systems and processes [M].The United States:Morgan Kaufmann,2005:455-458.

[8]HUANG Biao,Design and implementation of visual virtual machine X86VVM2 [D].Guangzhou:Guangdong University of Technology,2011(in Chinese).[黄彪.可视虚拟机X86VVM2的设计 与实现 [D].广州:广东工业大学,2011.]

[9]Bednarik R,Moreno A,Myller N,et al.Smart program visualization technologies:Planning a next step [C].Taiwan:Proceedings of the Fifth IEEE International Conference on Advanced Learning Technologies,2005:717-721.

[10]Xie Weibo,Fu Ting.Design and implementation of the virtual machine constructing on register [C].International Conference on Computer Science and Software Engineering,2008:424-430.

猜你喜欢

断点寄存器流程图
一种适用于继电保护在线整定的极小断点集求取算法
Lite寄存器模型的设计与实现
用Eclipse调试Python
一类无限可能问题的解法
一种程序源代码的标准化流程图转化方法∗
二进制翻译中动静结合的寄存器分配优化方法
移位寄存器及算术运算应用
三维地震在新疆伊宁矿区北区七号矿井勘探的应用
宁海县村级权力清单36条
Lx5280模拟器移植设计及实施