汇编语言课程设计报告.docx

上传人:b****3 文档编号:12678000 上传时间:2023-04-21 格式:DOCX 页数:50 大小:346.42KB
下载 相关 举报
汇编语言课程设计报告.docx_第1页
第1页 / 共50页
汇编语言课程设计报告.docx_第2页
第2页 / 共50页
汇编语言课程设计报告.docx_第3页
第3页 / 共50页
汇编语言课程设计报告.docx_第4页
第4页 / 共50页
汇编语言课程设计报告.docx_第5页
第5页 / 共50页
点击查看更多>>
下载资源
资源描述

汇编语言课程设计报告.docx

《汇编语言课程设计报告.docx》由会员分享,可在线阅读,更多相关《汇编语言课程设计报告.docx(50页珍藏版)》请在冰豆网上搜索。

汇编语言课程设计报告.docx

汇编语言课程设计报告

 

 

《汇编语言》课程设计报告

 

文件压缩程序

 

院系:

计算机科学与技术

专业:

信息安全

班级:

学号:

姓名:

指导教师:

 

2012年11月8日

 

 

一.需求分析

1.题目要求

编写一个文件压缩程序,程序功能:

1.压缩:

将输入文件压缩为输出文件。

2.解压:

上面生成的压缩的输入文件解解压缩到输出文件,如果不是上面压缩的格式(根据文件特征识别),报错。

压缩算法可以自行选择。

2.需求分析

1.基本的算术运算和逻辑位运算。

2.用汇编实现简单的数据结构。

3.文件I/O系统调用。

4.可执行程序的参数使用。

5.综合解决问题的能力。

一.程序设计

1.压缩算法

程序中采用的是Lempel-Ziv压缩算法。

Lempel-Ziv,简称LZ,拥有LZ77,LZ78,LZW几种不同的演变算法!

LZ是一种典型的字典型压缩算法,巧妙的利用字典,减少信息量。

LZ77,LZ78就是现在流行的Zip压缩算法的前身。

LZ77,LZW这种字典型的数据压缩方式压缩比例远远比单纯的从编码上的优化的压缩要高。

而且这种压缩算法无论是在压缩还是在解压,执行效率都比以前的编码优化压缩要高得多!

下面主要介绍一下LZ77算法的原理:

lz77算法是Lempel-Ziv在1977年发明的。

LZ77算法有很多派生的算法(其中包括LZSS)。

它们大都基本上是类似的。

LZ77算法总是包括一个(slidingwindow滑动窗口,大概是一个容量可变的存储器)和一个预读缓存器(readaheadbuffer)。

这个slidingwindows基本上说是一个历史缓存器,用来存放前n个字节的输入流(inputstream)。

一个slidingwindow大小可以从0K到64K。

LZSS使用的是一个4K的slidingwindow,这也是通常使用的大小。

预读缓存器与slidingwindow是对应的。

它保存这个流的前n个字节。

预读缓存器的大小通常在0到258K之间。

这个算法就是基于这个建立的。

用下n个字节填充预读缓存器(n是预读缓存器的大小)。

查找这个slidingwindow,找到和预读缓存器中的数据最匹配的。

如果这个匹配的长度大于最小匹配长度(最小匹配长度取决于编码器,通常取决于slidingwindow的长度。

比如一个4K的slidingwindow,最小匹配长度为2),然后输出一个,长度(length)是这个匹配的长度,距离(distance)是在向后多少字节的地方这个匹配被找到的。

为了弄清以上的问题,我们来看一个例子:

(我们要用一个10字节长的slidingwindow,和一个5字节的预读缓存器)

 

输入流(InputStream):

AAAAAAAAAABABAAAAA

 -------------------------=======

    SlidingWindow        ReadAhead

                           Buffer

 

假设这个slidingwindow中包含10个A(在上面这个例子中),这就是最后被读入的10个字节。

预读缓存器中包含BABAA .编码第一步,在slidingwindow中找与预读缓存器中的数据大于2个的匹配。

在slidingwindow中没有找到BABAA,所以输出B到数据流中。

然后,slidingwindow移动一个字节。

 

当前输出流:

B

 

输入流:

    AAAAAAAAAABABAAAAA

     --------------------------=======

      SlidingWindow        ReadAhead

                            Buffer

 

现在,预读存储器中包含ABAAA。

然后再与slidingwindow比较。

可知,在slidingwindow中可以找到AB这个长度为2的匹配,它是在从现在向前2字节的位置。

于是输出一个

length为2,backwardsdistance也是2,输出<2,2>。

 

当前输出流:

B<2,2>

输入流:

    AAAAAAAAAABABAAAAA

          --------------------------=======

          SlidingWindow      ReadAhead

                              Buffer

预读缓存器中包含AAAAA。

好幸运!

在slidingwindow中向前8个字节的地方有一个长度为5的匹配。

输出就是<5,8>。

 

最后输出流:

B<2,2><5,8>

 

很简练是不是?

现在让我们来将这个流解码。

假设最后解码的10个字节是10个A。

 

输入流:

AAAAAAAAAAAB<2,2><5,8>

 

预读缓存器和slidingwindow在解码时是用不上的。

前十个A是字面上的,所以它们像这样被解码:

 

当前输出流:

AAAAAAAAAA

 

下一个字节的B也是一个literal,所以像这样解码:

 

当前输出流:

AAAAAAAAAAB

 

然后遇到了一个

<2,2>,意思是向后退两个字节复制2字节到输出流:

 

当前输出流:

AAAAAAAAAAB

                          <--

                          2bytesback

    AAAAAAAAA AB AB

                        ---

                        |-->

                       copiedtooutput

 

接下来是<5,8>,意思是退后8字节,复制5字节到输出:

 

当前输出流:

      AAAAAAAAAABAB

               <--------------

                  8bytesback

    AAAAA AAAAA BABAAAAA

               ------------

                    |---------->

  copiedtooutput

 

现在有个问题。

怎么确定哪个字节是literal,哪个字节表示

解决办法是用将数据编成一个组用一个8位的数据作为前缀来标识。

当这个前缀字节转换成二进制时,用标记on和off来表示后8个字节是literal还是

例如,编码流(在上一个例子中)是:

B<2,2><5,8>

这里有一个literal和两个distance。

前缀字节应该是011(0表示literal,1表示),然后在剩下的5个位上补0,这样凑成了一个字节:

01100000->96(十进制)。

最后的流应该是:

96B2258

LZ编码的编码方法非常简捷,译码也很简单,可以一边译码一边建立字典,只要传输字典的大小,无需传输字典本身。

当编码的信源序列增长时,编码效率会提高,平均码长会逼近信源熵。

2.压缩程序设计

程序设计流程:

1.初始化单个字符的字符串表;

2.读第一个字符。

将该字符设置为(前缀字符串)。

3.读取下一个字符,K。

4.如果到了文件末尾,则输出码字并退出。

5.如果k在表中,将K取代,然后转到步骤3。

6.输出码字

7.将K置入字符串表中。

8.将K设置为

返回步骤3。

注:

是一个码字,它表示在表中的字符串。

当一个新的字符k被读取,在表中搜索K组合。

如果这组合的发现,将设置为该组合的码字,然后读入下一个字符。

如果没有发现,这样的组合将被添加到字符串表中,码字被写入到输出流中,并将K设置为

 

3.解压程序设计

解压缩算法通过分析把每一个收到的码字还原为前缀字符串与拓展字符,建立了一个相同的表。

将扩展字符压入堆栈中,前缀字符串再次转换,直到它已经成为一个单一的字符为止。

这样就完成了解压。

解压后的码字经由弹出堆栈输出,并且在表中建立一个新的条目。

当输入流中包含KKK的序列时(k已经在字符串表中),解压缩算法终止,其中已经是在压缩机的表。

这序列将在下面的第3步处理。

程序设计流程:

1.读取第一个输入码字,分配给,K,oldcode和finchar。

输出K。

2.读取下一个码字,分配给incode。

如果到了文件末尾,则退出。

3.如果不在表中(例如kkk),则

a.把finchar压入堆栈。

b.设置和incode为oldcode。

4.如果在表中,则

a.将.字符压入堆栈。

b.将.码字送入

c.跳转到第4步。

5.将oldcode和finchar送入,输出finchar。

6.当有字符在堆栈中,弹出栈顶并输出字符。

7.将k添加到表中。

8.将incode设置为oldcode。

9.跳转到第2步。

注:

这里使用的算法拥有一个额外的特点,输出的码字有可变的长度。

开始时码字长度为9bit,一旦码的数量唱过当前码字大小,码字中的比特数将会增加。

当字符串表已满,一段明文已经被解压缩程序翻译出,并且将字符串表初始化。

此程序使用的码字的最大大小为12bit,总共4096个代码。

当字符串表达到当前码字大小的最大值时,解压缩程序实现码字大小的改变,从这一点上,码字的大小是增加的。

但要记住的是,在任何时刻解压缩程序的字符串表和压缩程序的字符串表的原始数据是相同的。

 

三.程序测试

1.压缩测试

打开压缩程序界面,输入待压缩文件路径和文件名,以及压缩后的文件存储路径和文件名。

如下所示:

回车后界面关闭,在存储路径下可以看到新生成的文件:

打开压缩前的文件12.txt,可以看到:

 

 

再打开压缩后生成的文件23.txt,可以看到:

 

因为压缩程序对原文件进行编码,打乱其原先的编码,导致记事本打开压缩文件时出现乱码。

那么原文件是否得到了压缩呢?

经查看原文件和压缩文件的属性可知,原文件大小为365KB,压缩后为284KB,压缩率约为77.8%。

可见,原文件的确得到了压缩。

2.解压缩测试

同样的,打开解压缩程序界面,输入待解压缩文件路径和文件名,以及解压缩后的文件存储路径和文件名。

将解压后的文件打开,可以发现跟原文件相同:

3.错误的命令下对压缩程序和解压缩程序的测试

a.缺乏输出路径

程序会在压缩程序所在的目录下生成压缩文件1.txt,是即为默认存储目录。

b.待压缩文件不存在

压缩程序不报错,但仍然会在指定目录下生成一名为2.txt的空文件。

c.待压缩文件非文本文件

压缩程序不报错,会在指定目录下生成一名为1.txt的空文件。

四.特点、不足以及改进意见

1.特点

a.对英文文本文件的压缩率要大于中文文本文件压缩率。

测试如下:

中文文件:

12.txt,压缩前大小:

365KB,压缩后:

284KB,压缩率:

77.8%

英文文件:

Escapes.txt,压缩前:

312KB,压缩后:

159KB,压缩率:

51.0%

中文文件:

Piaget.txt,压缩前:

1765KB,压缩后:

1247KB,压缩率:

70.1%

英文文件:

House.txt,压缩前:

1940KB,压缩后:

992KB,压缩率:

51.1%

由上述测试可以明显看出压缩程序对英文文件的压缩率要远远高于中文文件。

分析其原因,应该是因为Lempel-Ziv压缩算法是一种字典压缩算法,字典压缩的原理是构建一个字典,用索引来代替重复出现的字符或字符串。

而根据文字的组成可知,英文文本相对于中文文本来说更容易出现相同的字符或字符串,因而能够拥有更高的压缩率。

为了对此进行验证,可以将压缩文件再次压缩,由于压缩文件已经是乱码,重复出现的字符或字符串会很少,再次压缩的压缩程度必然不大。

经测试,把12.txt的压缩文件23.txt再次压缩发现,新生成的压缩文件大小为377KB,甚至比原文件都要大。

b.采用多个宏定义,包括文件打开、读取、写入、关闭、偏移指针等宏,简化了在程序中需要用到的对文件的频繁操作,而且程序代码更清晰,便于阅读。

c.压缩所用时间短,因为只是一个不大的程序,所以耗时短。

2.不足及改进意见

不足和改进的建议:

程序缺少必要的信息提示,尤其是对命令行操作错误和文件读取错误的提示,自己操作时会比较熟悉相关操作,但他人在出错后难以明白原因。

因而需要增加一些必要的信息提示,便于其他操作者操作失误时分析自己的原因。

五.体会

在学习汇编语言之前,我只学习过C语言的知识,而汇编语言同之相比,有着很大的区别.特别是各种符号代号繁多,很容易出错.在程序的编写的时候,这一点的体会尤其很深刻.因此在编写程序时,我不得不总是对照着书本和其他途径获取的一些实例进行对照,以避免出现各种细节上的错误.

在程序实现过程中,尤其需要细心。

一个很小的字符乃至标点的错误,很可能就会使编译无法实现.这点让我深有体会。

要把理论转化为实践是必须的,学生必须经常动手,课程设计就是这样的一个机会。

这次的课程设计做起来有些困难,在开始的一段时间里,几乎都是在网上查找一些资料和学习一些新的函数和功能,弄懂了很多以前没弄明白的知识。

体会到只有平时多练习,多看程序才能自己编写程序、调试程序。

通过这次的课程设计,我对汇编语言有了更加深入的了解,也学到了很多新知识。

 

六.源程序及程序清单

1.程序清单

a.汇编语言课程设计报告

b.程序源程序和可执行程序

1.LZCOMP.ASM压缩程序源码

2.LZDCMP.ASM解压缩程序源码

3.MACROS.MAC宏代码

4.LZCOMP.EXE压缩程序

5.LZDCMP.EXE解压缩程序

2.源代码

宏:

.xlist

getchrmacro

movah,1

int21h

endm

putchrmacrochr

ifdif

,

movdl,chr

endif

movah,2

int21h

endm

getauxmacro

movah,3

int21h

endm

putauxmacrochr

ifdif

,

movdl,chr

endif

movah,4

int21h

endm

putprnmacrochr

ifdif

,

movdl,chr

endif

movah,5

int21h

endm

dciomacrochar

ifnb

movdl,0ffh

else

ifdif

,

movdl,char

endif

endif

movah,6h

int21h

endm

dcinnemacro

movah,7h

int21h

endm

noechomacrofunc

ifnb

ifdif,

movax,0800H+func

endif

else

movax,0800H

endif

int21H

endm

printmacrostr

movdx,offsetstr

movah,9h

int21h

endm

inputmacrobuf

movdx,offsetbuf

movah,0ah

int21h

endm

dskrstmacro

movah,0dh

int21h

endm

seldskmacrodrv

ifdif

,

movdl,drv

endif

movah,0eh

int21h

endm

openmacrofcb

movdx,offsetfcb

movah,0fh

int21h

endm

closemacrofcb

movdx,offsetfcb

movah,10h

int21h

endm

sfirstmacrofcb

movdx,offsetfcb

movah,11h

int21h

endm

snextmacrofcb

movdx,offsetfcb

movah,12h

int21h

endm

deletemacrofcb

movdx,offsetfcb

movah,13h

int21h

endm

seqrdmacrofcb

movdx,offsetfcb

movah,14h

int21h

endm

seqwrtmacrofcb

movdx,offsetfcb

movah,15h

int21h

endm

createmacrofcb

movdx,offsetfcb

movah,16h

int21h

endm

renamemacrofcb

movdx,offsetfcb

movah,17h

int21h

endm

getdrvmacro

movah,19h

int21h

endm

setdtamacrobuf

movdx,offsetbuf

movah,1ah

int21h

endm

rndrdmacrofcb

movdx,offsetfcb

movah,21h

int21h

endm

rndwrtmacrofcb

movdx,offsetfcb

movah,22h

int21h

endm

getsizmacrofcb

movdx,offsetfcb

movah,23h

int21h

endm

setrelmacrofcb

movdx,offsetfcb

movah,24h

int21h

endm

setvecmacroint,addr

movdx,offsetaddr

movax,2500H+int

int21h

endm

rndbrdmacrofcb,siz

movdx,offsetfcb

ifdif,

movcx,siz

endif

movah,27h

int21h

endm

rndbwrmacrofcb,siz

movdx,offsetfcb

ifdif,

movcx,siz

endif

movah,28h

int21h

endm

parsemacrostring,fcb,flag

ifdif<[si]>,

movsi,offsetstring

endif

ifdif<[di]>,

movdi,offsetfcb

endif

ifdif,

movax,2900H+flag

else

movah,29H

endif

int21h

endm

getdatmacroyear,month,day

movah,2ah

int21h

movyear,cx

movmonth,dh

movday,dl

endm

setdatmacroyear,month,day

movcx,year

movdh,month

movdl,day

movah,2bh

int21h

endm

gettimmacrohour,minute,second

movah,2ch

int21h

movhour,ch

movminute,cl

movsecond,dh

endm

settimmacrohour,minute,second

movch,hour

movcl,minute

movdh,second

xordl,dl

movah,2dh

int21h

endm

wrtvermacroonoff

ifdif,

movax,2E00H+onoff

else

movah,2EH

endif

int21h

endm

getdtamacrobuf

pushbx

pushes

movah,2fh

int21h

movwordptrbuf,bx

movwordptrbuf+2,es

popes

popbx

endm

dosvermacro

movah,30h

int21h

endm

breakmacroonoff

ifnb

ifdif

,

movdl,onoff

endif

movax,3301H

else

movax,3300H

endif

int21h

endm

getvecmacroint

movax,3500H+int

int21h

endm

freemacrodrv

ifnb

ifdif

,

movdl,drv

endif

else

xordl,dl

endif

movah,36h

int21h

endm

credirmacropath

movdx,offsetpath

movah,39h

int21h

endm

remdirmacropath

movdx,offsetpath

movah,3ah

int21h

endm

setdefmacropath

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1