电子科技大学 软件开发环境 实验报告.docx
- 文档编号:10953517
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:68
- 大小:409.56KB
电子科技大学 软件开发环境 实验报告.docx
《电子科技大学 软件开发环境 实验报告.docx》由会员分享,可在线阅读,更多相关《电子科技大学 软件开发环境 实验报告.docx(68页珍藏版)》请在冰点文库上搜索。
电子科技大学软件开发环境实验报告
电子科技大学
实验报告
学生姓名:
郭小明学号:
2011060100010
一、实验室名称:
主楼A2-412
二、实验项目名称:
软件开发环境试验-----Huffman编码实验
3、实验原理:
2.1分割函数的三项原则
分割函数的三项原则包括:
与其写注释,不如写函数;重复就是罪恶;函数不要超过50行至70行。
关于分割函数三原则的具体含义,请见教材和课堂教学PPT关于电话本的内容。
这里不再赘述。
2.2Huffman编码的基本原理
本实验要求使用Huffman编码算法,实现对文件的压缩和解压。
因此,我们首先介绍huffman的编码算法。
Huffman编码是一种可变长编码方式,是由美国数学家DavidHuffman创立的,是二叉树的一种特殊转化形式。
编码的基本原理是:
将使用次数多的代码转换成长度较短的编码,而使用次数少的代码则可以使用较长的编码,并且保持编码的唯一可解性。
指导书试验原理部分较多,在这里就不做粘贴复制了。
四、实验目的:
本实验总体目的是,通过使用huffman编码算法从而实现文件的压缩和解压,以达到使学生掌握并灵活运用分割函数的三项原则。
5、实验内容:
本实验要求实现一个exe程序。
这个程序按照huffman编码方式,同时包含了压缩功能和解压功能。
用户通过以下命令进行压缩:
C:
\>test.exe–cuncompress_filenamecompress_filename
上述命令中,test.exe是程序名,-c表示要进行压缩。
uncompress_filename是要压缩的文件名,可以包含路径信息,而compress_filename是压缩之后的文件名,同样可以包含路径信息。
用户可以通过如下命令进行解压:
C:
\>test.exe–ucompress_filenameuncompress_filename
上述命令中,-u表示要执行解压命令。
compress_filename是要解压的文件名,可以包含路径信息;uncompress_filename就是解压后所得到的文件,同样可以包含路径信息。
提示:
在实现test.exe程序时,需要考虑如何存储huffman树或者编码表或者词频表等等。
本实验要求实现两个版本的test.exe程序,一是C语言版本的,二是C++版本的。
对这两个版本的要求如下:
●对于每一个版本的程序,需要在实验报告中给出函数调用关系图、流程处理关系图以及它们的文字说明等内容;
●对于每一个版本的程序,都需要在实验报告中给出源代码。
为了便于查重,代码中注释的比例要占到总行数的20%;
●C++版本的程序,需要给出类关系图。
实验报告的评分标准,包括以下几个方面:
●实验报告是否规范
●实验报告内容是否详实
●实验报告中是否包含了函数调用图、流程图、类图以及它们的文字说明
●实验报告中的代码注释是否达到要求
●程序是否正确无误
●程序是否严格按照分函数的原则编写
●C++版本的程序类关系的耦合度如何
●程序实现是否考虑了大文件情况
六、实验器材(设备、元器件):
PC机,vs2008软件平台。
七、实验数据及结果分析:
代码见附件。
huffmanForC
文件中函数列表如下:
///统计词频时用于查找是否已经记录过,记录过的话返回下标,没有则返回0
intisInNode(intvalue)
//获取文件词频,记录在NodehuffmanNode[260]的节点数组当中
voidcalWeight(char*file)
/*得到待压缩文件的总字节数,权值为几就代表着有多少个字节*/
intgetSumBytes()
//获取压缩后文件的总bit数
intgetSumBits()
//建立huffman树根据huffman树的特性,具有n个节点的huffman树的具有2n-1个节点
//n值由全局变量count值来确定,该函数主要用来初始化Huffman树的所有节点信息
voidcreateHufmanTree(Node*huffmanTree)
/*字符编码,从构建好的Huffman树当中读取每个叶子节点的huffman编码,并将叶子节点的信息放入到code[]中*/
HCode*getHuffmanCode(Node*huffmanTree,HCode*HC,intcode[])
/*
将编码表写入默认文件当中,并在结尾存入叶子节点数(count)与压缩后文件的总bit数
111100027
...........
...........
#sum_bit##count#
*/
voidfreToFile(intcode[],HCode*HC)
//由于词频表是按照字符串方式存储的叶子节点信息,读取出来的字符串需要转换成int值再使用
intpowmy(inta,intb)
/*从编码表文件读取相应信息以用来解压文件,读取信息包括编码和叶子信息*/
HCode*freFromFile(intcode[],HCode*HC)
/*压缩文件*/
voidcompress_file(char*file1,char*file2)
/*用于在解压的时候将读取到的ASCII码转换为二进制数*/
intswap(intdata)
/*进行文件的解压*/
voiduncompress_file(char*file1,char*file2)
//主函数
intmain(intargc,char**argv)
函数关系调用图:
向下箭头为顺序依次调用,斜线为函数内调用
输入-cargv[2]argv[3]
输入-c命令
isInNode()
获取argv[2]文件中的词频信息
calWeight(argv[2])
根据词频信息建立Huffan树
createHufmanTree()
getSumBytes()
getHuffmanCode()
获取Huffman编码
getSumBits()
compress_file()
将argv[2]文件使用编码压缩成argv[3]
将编码信息写入编码表文件,以备解压使用
freToFile()
输入-uargv[2]argv[3]
输入-u命令
powmy()
freFromFile()
从词频表当中读取编码信息
swap()
将argv[2]文件解压为argv[3]文件
uncompress_file()
代码见附件。
上面操作实现了将file.txt压缩成out.txt(同时生成了默认词频表文件dic.txt),然后实现了解压缩功能。
实验文件列表:
file.txt为源文件,out.txt为压缩文件,out1.txt为解压出来的文件
下面是dic.txt的部分信息,存放的依次是Huffman编码,对应的ASCII码
压缩后产生的文件,确实是乱码
解压后的文件,与压缩前的文件,大小内容完全一致。
C++
Controll类
classControll//:
publicHuffmanTree
{
public:
voidcompress_file(constchar*,constchar*,constchar*);
voiduncompress_file(constchar*,constchar*,constchar*);
voidfreFromFile(constchar*,char**,char*,int*);
intpowmy(int,int);
};
HuffmanNode类
classHuffmanNode{
public:
charinfo;//结点信息
doubleweight;//结点权值
intparent,lchild,rchild;//父亲结点,左右孩子结点
HuffmanNode(){
parent=lchild=rchild=-1;
}
HuffmanNode(constchar&data,constdouble&wt,constint&pa=-1,constint&lch=-1,constint&rch=-1){
info=data;
weight=wt;
parent=pa;
lchild=lch;
rchild=rch;
}
};//classHuffmanNodeend
Code类
/*现在我把它调出来为的就是在controlll类当中使用这个类*/
classCode{
public:
Code():
length(10){ptr=newchar[length];}
~Code(){delete[]ptr;}
char*ptr;
constintlength;
};
HuffmanTree类
classHuffmanTree{
public:
HuffmanTree(constint&s=100){
maxSize=(s>100?
s:
100);
arrayTree=newHuffmanNode[maxSize];
currentSize=0;
codeArray=0;
}
~HuffmanTree(){
delete[]arrayTree;
if(codeArray!
=0)
delete[]codeArray;
}
voidrun(constchar*,constchar*);
intgetSumBytes();//定义待压缩文件的总bytes数
intcurrentSize;//当前数组大小
HuffmanNode*arrayTree;//哈夫曼结点数组
Code*codeArray;//数组大小为currentSize
intsum_bits;//定义压缩后文件的总bit数
private:
intmaxSize;//数组最大值
//intsum_bytes;
voidinsert(constchar&,constdouble&);//插入结点
voidcreateHuffmanTree();//创建哈夫曼树
voidcreateHuffmanCode();//创建哈夫曼编码
voidwriteCodeToFile(constchar*);//将Huffman编码写入到词频表文件当中
intfindPosition(constchar&)const;//返回字符在arrayTree[]中的位置
intisEqual(constchar*s)const;//判断s是否存在于编码系统中,若存在则返回s在编码系统中的位置,否则返回-1
voidreverse(chararr[]);
};//classHuffmanTreeend
Code类
类关系图
HuffmanTree类类
HuffmanNode类
Control类
C++版本的实验过程总体类似C语言的实验过程,截图类似上面。
两程序总体程序设计思想:
压缩文件命令:
(1)首先读取待压缩文件,建立词频信息的存储。
(2)然后根据存储的词频信息,建立Huffman树。
(3)然后根据建立后的Huffman树,生成编码表信息。
(4)根据编码表信息再次逐字节的的读取带压缩文件并且压缩文件。
(5)最后将编码表信息和相关文件信息写进存储文件,以备解压使用。
解压命令
(1)从编码表存储文件当中读出编码信息。
(2)根据相关编码信息对压缩文件进行解码,生成解压缩文件。
两份源代码打包一并交到了系统里面,以备老师查看!
电子科技大学
实验报告
学生姓名:
郭小明学号:
2011060100010
一、实验室名称:
主楼A2-412
二、实验项目名称:
软件开发环境实验二:
流程控制语句反汇编
三、实验原理:
VS2008的反汇编调试和反汇编代码规律。
四、实验目的:
本实验总体目的是,通过使用VisualStudio2008查看if、if/else、do/while/for等类型语句的反汇编代码,以达到掌握流程控制语句识别的目的。
五、实验器材(设备、元器件):
PC机,VS2008反汇编编码调试软件
六、实验步骤:
2.2if语句的反汇编
在实验报告中需要给出代码清单2的解释。
代码清单2
int_tmain(intargc,_TCHAR*argv[])
{
inti=3;
if(i>3)
{
i=4;
}
return0;
}
反汇编代码
inti=3;
00DD138Emovdwordptr[ebp-8],3
if(i>3)
00DD1395cmpdwordptr[ebp-8],3
00DD1399jle00DD13A2
{
i=4;
00DD139Bmovdwordptr[ebp-8],4
}
return0;
00DD13A2xoreax,eax
反汇编代码清单2,下面进行解释:
inti=3;
00DD138Emovdwordptr[ebp-8],3
由课上讲述的结论:
在使用了EBP寻址的函数中,ebp-偏移量就是局部变量的地址。
我们在程序当中定义了一个局部变量inti=3。
int_tmain(intargc,_TCHAR*argv[])
{
00DD1370pushebp
00DD1371movebp,esp
以上是该程序入口处的反汇编代码,看得出来程序首先将ebp压栈,然后将现在的栈顶指针esp赋值给ebp(由于栈是由高到低的顺序生长的,所以此时ebp-n就可以表示ebp后面n字节的地址了),然后我们再定义inti=3;刚好压栈后存储在ebp的后面,,并且由于VS2008为了防止溢出攻击,在ebp后面空出了4个字节,然后再分配四个字节存放i变量,于是i变量的地址就变成了ebp-8,并且int类型变量是4个字节,所以就在[ebp-8]
加上dwordptr用来指明数据的字节数
00DD1395cmpdwordptr[ebp-8],3
同上dwordptr[ebp-8]是指明数据字节数,获取i数据值,cmp是将i值与3进行比较,其实就是执行i-3,然后在标志寄存器(PSW----ProgramStatusWord)的各位反应比较的结果。
00DD1399jle00DD13A2
jle(jle,jumpiflightorequal)的含义是第一个操作数小于或等于第二个操作数时跳转(当然此时就是通过标志寄存器(PSW----ProgramStatusWord)中的数值来判断)。
然后我们观察跳转地址00DD13A2其实就是00DD13A2xoreax,eax最后一句return0的代码。
i=4;
00DD139Bmovdwordptr[ebp-8],4
这是if条件语句里面的代码,将i值赋值为4,同理,dwordptr[ebp-8]是通过ebp-8找寻到i的地址单元,然后dwordptr说明字节数,mov指令将4赋给这个地址(就是i的存放地址);
return0;
00DD13A2xoreax,eax
程序返回0
eax清零
代码清单3
int_tmain(intargc,_TCHAR*argv[])
{
inti=3;
if(i<3)
{
i=4;
}
return0;
}
下面是代码清单3的反汇编代码和解释。
inti=3;
0122138Emovdwordptr[ebp-8],3
if(i<3)
01221395cmpdwordptr[ebp-8],3
01221399jge012213A2
{
i=4;
0122139Bmovdwordptr[ebp-8],4
}
return0;
012213A2xoreax,eax
*******************************************************************
inti=3;
0122138Emovdwordptr[ebp-8],3
定义一个int型的变量i,赋值为3,[ebp-8]ebp-8是i变量地址,[ebp-8]是i变量,dwordptr是指明该地址数据由4字节构成,然后通过mov指令将3赋值给i。
if(i<3)
01221395cmpdwordptr[ebp-8],3
dwordptr[ebp-8]是指明数据字节数,获取i数据值(ebp-8是i变量的地址,[ebp-8]是i变量),cmp是将i值与3进行比较,其实就是执行i-3,然后在标志寄存器(PSW----ProgramStatusWord)的各位反应比较的结果。
01221399jge012213A2
通过与代码清单2的比较我们可以得出,jge(jge,jumpifgreaterorequal)是当第一个操作数大于或者等于第二个操作数的时候进行跳转。
且跳转地址就是return0代码的地址。
i=4;
0122139Bmovdwordptr[ebp-8],4
这是if条件语句里面的代码,将i值赋值为4,同理,dwordptr[ebp-8]是通过ebp-8找寻到i的地址单元,然后dwordptr说明字节数,mov指令将4赋给这个地址(就是i的存放地址);
012213A2xoreax,eax
程序返回0
eax清零
代码清单4
int_tmain(intargc,_TCHAR*argv[])
{
inti=3;
if(i==3)
{
i=4;
}
return0;
}
下面是代码清单4的反汇编代码及解释
inti=3;
002B138Emovdwordptr[ebp-8],3
if(i==3)
002B1395cmpdwordptr[ebp-8],3
002B1399jne002B13A2
{
i=4;
002B139Bmovdwordptr[ebp-8],4
}
return0;
002B13A2xoreax,eax
}
***************************************************************
inti=3;
002B138Emovdwordptr[ebp-8],3
定义一个int型的变量i,赋值为3,[ebp-8]ebp-8是i变量地址,[ebp-8]是i变量,dwordptr是指明该地址数据由4字节构成,然后通过mov指令将3赋值给i。
if(i==3)
002B1395cmpdwordptr[ebp-8],3
dwordptr[ebp-8]是指明数据字节数,获取i数据值(ebp-8是i变量的地址,[ebp-8]是i变量),cmp是将i值与3进行比较,其实就是执行i-3,然后在标志寄存器(PSW----ProgramStatusWord)的各位反应比较的结果。
002B1399jne002B13A2
通过与代码清单2的比较我们可以得出,jne(jne,jumpifnotequal)是当第一个操作数不等于第二个操作数的时候进行跳转。
且跳转地址就是return0代码的地址。
i=4;
002B139Bmovdwordptr[ebp-8],4
这是if条件语句里面的代码,将i值赋值为4,同理,dwordptr[ebp-8]是通过ebp-8找寻到i的地址单元,然后dwordptr说明字节数,mov指令将4赋给这个地址(就是i的存放地址);
002B13A2xoreax,eax
程序返回0
eax清零
实验有要求:
另外,还可以自行实验<=、>=时的情况。
在实验报告中,给出这些情况的反汇编代码及解释。
最后,在实验报告中,总结出条件判断语句的反汇编代码规则。
下面是在>=情况下的反汇编代码:
inti=3;
00CF138Emovdwordptr[ebp-8],3
//if(i==3)
if(i>=3)
00CF1395cmpdwordptr[ebp-8],3
00CF1399jl00CF13A2
{
i=4;
00CF139Bmovdwordptr[ebp-8],4
}
return0;
00CF13A2xoreax,eax
*********************************************
下面只是解释这句不同的代码:
00CF1399jl00CF13A2
通过与代码清单2的比较我们可以得出,jl(jne,jumpifless)是当第一个操作数小于第二个操作数的时候进行跳转。
且跳转地址就是return0代码的地址。
下面是<=代码的反汇编代码:
inti=3;
008C138Emovdwordptr[ebp-8],3
//if(i==3)
//if(i>=3)
if(i<=3)
008C1395cmpdwordptr[ebp-8],3
008C1399jg008C13A2
{
i=4;
008C139Bmovdwordptr[ebp-8],4
}
return0;
008C13A2xoreax,eax
********************************************************
008C1399jg008C13A2
通过与代码清单2的比较我们可以得出,jg(jne,jumpifgreater)是当第一个操作数大于第二个操作数的时候进行跳转。
且跳转地址就是return0代码的地址。
条件判断语句的反汇编代码规则:
由两条汇编指令构成:
cmp操作数1操作数2和jXX地址
cmp用于条件判断比较
Jxx用于在不符合判断的情况下跳转到后面的代码处
jg(jne,j
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子科技大学 软件开发环境 实验报告 软件 开发 环境 实验 报告