【关键字】精品
CRC校验
1 设计任务和要求
可以对内存中的一段数据计算出校验和(CRC校验),通过修改某个值验证该校验 和是否正确。
2 原理分析及程序设计
2.1原理分析
2.1.1 CRC简介
CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验,是一种利用除法及余数的原理来作错误侦测的编码,由于CRC易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,编码和解码方法简单,检错和纠错能力强,在各个领域广泛地应用。比如在我们解压一个RAR文件的时候,有时就会遇到CRC错误的提示。
CRC“校验和”是两个数据流采用二进制除法相除所得到的余数,其中被除数是需要计算校验和的信息数据流的二进制表示;除数是一个长度为n + 1的预定义的二进制数,通常用多项式的系数来表示。
2.1.2 CRC计算方法
在代数编码理论中,将一个码组表示为一个多项式,码组中各码元当作多项式的系数。例如 1100101 可以表示为1·x6+1·x5+0·x4+0·x3+1·x2+0·x+1,即 x6+x5+x2+1。设编码前的原始信息多项式为P(x),P(x)的最高幂次加1等于k;生成多项式为G(x),G(x)的最高幂次等于r;CRC多项式为R(x);编码后的带CRC的信息多项式为T(x)。计算方法是将P(x)乘以xr(即对应的二进制码序列左移r位),再除以G(x),所得余式即为R(x),R(x)即为所要求的CRC,其关系为:
举例来说,设信息码为1100,生成多项式为1011,即,,计算CRC的过程为:
即R(x)=x。注意到G(x)最高幂次r=3,得出CRC为010。
2.2 程序设计
2.2.1 CRC计算程序的编写
汇编语言清华大学出版社明白原理之后,就可以写出算法了,当然不能如计算一样用除法来进行计算,因为寄存器的限制,不能处理很长的一串数据;可以用XOR运算来代替减法计算,但是基于位运算的算法是非常慢的而且效率低下,内存空间足够的情况下,可以采用查表法来计算满足速度要求,由于算法的每一步递推都是以字节为单位的,这样就比传统的以位为单位的算法要快上十几倍。数据序列的长度越长,其体现的优越性就越高。
cal_crc16实现字符串CRC的计算。
我们的算法如下:
1. 将寄存器向右移动一个字节。
2. 将刚移出的哪个字节与字符串中的新字节做XOR运算,得出一个指向CRC TABLE[0……255]的索引。
3. 将索引所指的表值与寄存器做XOR运算。
4. 如数据没有全部处理完,则跳到步骤1。
2. 将刚移出的哪个字节与字符串中的新字节做XOR运算,得出一个指向CRC TABLE[0……255]的索引。
3. 将索引所指的表值与寄存器做XOR运算。
4. 如数据没有全部处理完,则跳到步骤1。
5.得到CRC的值
入口:DS:SI=buffer地址;CX buffer=长度;DX=CRC的初始值
出口 DX=CRC的结果
2.2.2 程序主界面的编写
(1)通过使用各种中断及字符画功能可以实现操作提示以及画出主界面,比如在16进制数的最后面加‘H’这样的单字符输入,我们可以采用DOS功能的02号中断;有些情况需要从键盘上输入字符,但不需要显示,我们可以采用DOS功能的08号中断。
(2)choose_function实现功能选择模块,当外界输入‘b’的时候,则调用windows_main开始计算;当外界输入‘c’的时候,则进行清屏;当外界输入‘q’的时候,则跳出。
(3)get_string及cal_len实现输入字符及长度的计算,即检测到中止符就跳出,长度存入len方便进行字符串的CRC计算。
(4)bin_to_hex将结果转为十六进制,我们把二进制转换为16进制是每四位一转的转,若
二进制表示的16进制数在“0到9”之间时,则只需将其ASCII码值加‘30h’;若二进制表示的16进制数在‘9’之外时,则将其ASCII码值加‘7h’即可。然后,我们将这个二进制数左移4位,继续转换,最后输出在屏幕上
3 程序流程图
3.1总体框图
图3-1 总体框图
3.2 choose_function功能模块框图
图3-2 choose_function功能模块框图
4 源代码
详见附录
5 运行结果
进入MF2KP,对程序进行编译、连接及运行,显示结果如下图所示。
图5-1
此时可以通过按下提示中的功能键进行功能选择,此时如果按下提示以外的按键会出现错误提示。
图5-2
正确选择功能后可以输入想要计算CRC的字符串,回车结束输入。
图5-3
此时可计算出刚才输入的字符串的CRC值。
图5-4
改变字符串最后一位进行CRC计算,CRC值发生了改变,满足设计要求。
图5-5
计算结束后可以按照提示清屏进行下次计算也可以退出程序。
6调试记录及与分析
最开始编写的程序运行结果无论什么数据CRC都是0,但是生成OBJ没有问题,算法也没有问题,调试界面跟踪计算中关键的入口出口及CRC,发现编写中因为寄存器不够用当时换DX保存CRC数据,但是计算CRC的子程序中存在没有改过来部分,导致了错误,更正后,问题得到解决。
图6-1
7 结束语
本次微机原理课程设计可以说是目前做过的课程设计中间最难的一个,刚刚接手可以说是一头雾水,虽然CRC这个词见过很多次,作用也明白,但是究竟算法是什么,如何实现等等完全一无所知。
经过几天的资料查询,发现困难重重,因为虽然原理讲的相当明白,但是实现起来就不是
一回事了,一开始决定用XOR代替减法实现CRC计算,但是三个循环嵌套写起来实在很麻烦,最后运行结果也出现很多问题,调试未果,只有尝试查表法,网上关于汇编的CRC资料真是少之又少,大部分都是C和VB的,最后终于在某个国外的网站上到了一点资料,特别是CRC的table,终于弄出了核心部分的算法,然后在同学的帮助下完成了界面的编写,再不断的完善及调试,终于完成了程序。
通过这次这次课程设计,我深深的认识到了课本上所教授的知识对于实际中的运用是远远不够的,需要在应用中不断的学习,另外编写过程中,常常有种想当然的想法,脑袋中构思的很好很强大,但是实现起来却有很多问题,使我明白了想象和实际是有变化和差距的,需要一点一点规划,摆正心态来认真去做,同时自己的基本功还不够扎实,需要多多学习和锻炼,才能不断提高。
8 参考文献
1 周佩玲编著.微机原理与接口技术(基于16位).电子工业出版社,2005年
2 罗万钧编著.汇编语言程序设计.西安电子科技大学出版社,1999年
3 杨立编著.微型计算机原理与汇编语言程序设计.中国水利水电出版社,2003年
4 沈美明、温冬婵编著.《IBM-PC汇编语言程序设计》.北京:清华大学出版社.1991年
5 微型计算机原理及应用 郑学坚 主编清华大学出版社2001年
9 附录
程序源代码
disp macro m
lea dx,m
mov ah,9
int 21h
endm;显示字符的宏定义
stack1 segment para stack 'stack'
db 200 dup (0)
stack1 ends
data1 segment
str0 DB 0AH,0DH, '*******************************************************************************$'
str1 DB 0AH,0DH, '* *$'
str2 DB 0AH,0DH, '* NNNNNNNNN sNNNNNNNNNNN NNNNNNNNN *$'
str3 DB 0AH,0DH, '* DNBNN=- zNNN- (NNNN< sNNNNz- *$'
str4 DB 0AH,0DH, '* =NNNB~ sNNN~ zNNN= ~NNNN+ *$'
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论