|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
请问下面的代码如何优化 |
作者:hswqs 栏目:单片机 |
这是TCP/IP协议中的校验和计算代码,使用中反复调用,KEIL C51编译后的汇编指令一大堆,谁能帮忙做个优化,汇编也行,不甚感激! unsigned int CHECKSUM(unsigned int xdata *check,unsigned int length) { //计算校验和 unsigned LONG data sum =0; unsigned int data i; for (i=0;i<(length)/2;i++) { sum+=*check++; } if(length&0x01)//表示长度为单数 { sum=sum+((*check)&0xff00); } sum=(sum&0xffff)+((sum>>16)&0xffff);//高16位和低16位相加 if(sum&0xffff0000) {//表示有进位 sum++; } return ( (unsigned int)(~((sum)&0xffff)) ); } |
2楼: | >>参与讨论 |
作者: hswqs 于 2006/12/27 14:45:00 发布:
上面程序KEIL编译后的代码如下 714: unsigned int CHECKSUM(unsigned int xdata *check,unsigned int length) C:0x3C01 903778 MOV DPTR,#0x3778 C:0x3C04 EE MOV A,R6 C:0x3C05 F0 MOVX @DPTR,A C:0x3C06 A3 INC DPTR C:0x3C07 EF MOV A,R7 C:0x3C08 F0 MOVX @DPTR,A C:0x3C09 AB05 MOV R3,0x05 C:0x3C0B AA04 MOV R2,0x04 715: { 716: //¼ÆËãУÑéºÍ 717: unsigned LONG data sum =0; 718: unsigned int data i; C:0x3C0D E4 CLR A C:0x3C0E F515 MOV 0x15,A C:0x3C10 F514 MOV 0x14,A C:0x3C12 F513 MOV 0x13,A C:0x3C14 F512 MOV 0x12,A 719: for (i=0;i<(length)/2;i++) C:0x3C16 F516 MOV 0x16,A C:0x3C18 F517 MOV 0x17,A C:0x3C1A EA MOV A,R2 C:0x3C1B C3 CLR C C:0x3C1C 13 RRC A C:0x3C1D FE MOV R6,A C:0x3C1E EB MOV A,R3 C:0x3C1F 13 RRC A C:0x3C20 FF MOV R7,A C:0x3C21 C3 CLR C C:0x3C22 E517 MOV A,0x17 C:0x3C24 9F SUBB A,R7 C:0x3C25 E516 MOV A,0x16 C:0x3C27 9E SUBB A,R6 C:0x3C28 5035 JNC C:3C5F 720: { 721: sum+=*check++; C:0x3C2A 903778 MOV DPTR,#0x3778 C:0x3C2D E4 CLR A C:0x3C2E 75F002 MOV B(0xF0),#0x02 C:0x3C31 122D7B LCALL C?ILDIX(C:2D7B) C:0x3C34 85F082 MOV DPL(0x82),B(0xF0) C:0x3C37 F583 MOV DPH(0x83),A C:0x3C39 E0 MOVX A,@DPTR C:0x3C3A FE MOV R6,A C:0x3C3B A3 INC DPTR C:0x3C3C E0 MOVX A,@DPTR C:0x3C3D FF MOV R7,A C:0x3C3E E4 CLR A C:0x3C3F FC MOV R4,A C:0x3C40 FD MOV R5,A C:0x3C41 E515 MOV A,0x15 C:0x3C43 2F ADD A,R7 C:0x3C44 F515 MOV 0x15,A C:0x3C46 E514 MOV A,0x14 C:0x3C48 3E ADDC A,R6 C:0x3C49 F514 MOV 0x14,A C:0x3C4B ED MOV A,R5 C:0x3C4C 3513 ADDC A,0x13 C:0x3C4E F513 MOV 0x13,A C:0x3C50 EC MOV A,R4 C:0x3C51 3512 ADDC A,0x12 C:0x3C53 F512 MOV 0x12,A 722: } C:0x3C55 0517 INC 0x17 C:0x3C57 E517 MOV A,0x17 C:0x3C59 70BF JNZ C:3C1A C:0x3C5B 0516 INC 0x16 C:0x3C5D 80BB SJMP C:3C1A 723: if(length&0x01 |
3楼: | >>参与讨论 |
作者: hswqs 于 2006/12/27 14:48:00 发布:
这段是循环体的代码,时间重点消耗区,如何改进? for (i=0;i<(length)/2;i++) C:0x3C16 F516 MOV 0x16,A C:0x3C18 F517 MOV 0x17,A C:0x3C1A EA MOV A,R2 C:0x3C1B C3 CLR C C:0x3C1C 13 RRC A C:0x3C1D FE MOV R6,A C:0x3C1E EB MOV A,R3 C:0x3C1F 13 RRC A C:0x3C20 FF MOV R7,A C:0x3C21 C3 CLR C C:0x3C22 E517 MOV A,0x17 C:0x3C24 9F SUBB A,R7 C:0x3C25 E516 MOV A,0x16 C:0x3C27 9E SUBB A,R6 C:0x3C28 5035 JNC C:3C5F 720: { 721: sum+=*check++; C:0x3C2A 903778 MOV DPTR,#0x3778 C:0x3C2D E4 CLR A C:0x3C2E 75F002 MOV B(0xF0),#0x02 C:0x3C31 122D7B LCALL C?ILDIX(C:2D7B) C:0x3C34 85F082 MOV DPL(0x82),B(0xF0) C:0x3C37 F583 MOV DPH(0x83),A C:0x3C39 E0 MOVX A,@DPTR C:0x3C3A FE MOV R6,A C:0x3C3B A3 INC DPTR C:0x3C3C E0 MOVX A,@DPTR C:0x3C3D FF MOV R7,A C:0x3C3E E4 CLR A C:0x3C3F FC MOV R4,A C:0x3C40 FD MOV R5,A C:0x3C41 E515 MOV A,0x15 C:0x3C43 2F ADD A,R7 C:0x3C44 F515 MOV 0x15,A C:0x3C46 E514 MOV A,0x14 C:0x3C48 3E ADDC A,R6 C:0x3C49 F514 MOV 0x14,A C:0x3C4B ED MOV A,R5 C:0x3C4C 3513 ADDC A,0x13 C:0x3C4E F513 MOV 0x13,A C:0x3C50 EC MOV A,R4 C:0x3C51 3512 ADDC A,0x12 C:0x3C53 F512 MOV 0x12,A 722: } C:0x3C55 0517 INC 0x17 C:0x3C57 E517 MOV A,0x17 C:0x3C59 70BF JNZ C:3C1A C:0x3C5B 0516 INC 0x16 C:0x3C5D 80BB SJMP C:3C1A |
4楼: | >>参与讨论 |
作者: 农民讲习所 于 2006/12/27 14:48:00 发布:
sam改用联合 |
5楼: | >>参与讨论 |
作者: 农民讲习所 于 2006/12/27 14:50:00 发布:
length/2用变量代替 |
6楼: | >>参与讨论 |
作者: 农民讲习所 于 2006/12/27 14:51:00 发布:
unsigned LONG data sum 中data描述去掉 |
7楼: | >>参与讨论 |
作者: hswqs 于 2006/12/27 15:06:00 发布:
所长可否帮忙稍作改动贴出来,上面说的不能全理解 |
8楼: | >>参与讨论 |
作者: xwj 于 2006/12/27 15:10:00 发布:
8位机不要用32位加法,改成16位 |
9楼: | >>参与讨论 |
作者: xwj 于 2006/12/27 15:15:00 发布:
真要优化建议用汇编重新写过,要注意进位哦 |
10楼: | >>参与讨论 |
作者: hswqs 于 2006/12/27 15:15:00 发布:
是否如下所示,具体计算应该怎么写? union crc { unsigned LONG dwords; struct {unsigned int high;unsigned int low;}words; struct {unsigned CHAR byte3;unsigned CHAR byte2;unsigned CHAR byte1;unsigned CHAR byte0;}bytes; }; crc sum; unsigned int CHECKSUM(unsigned int xdata *check,unsigned int length) { //计算校验和 ................ } |
11楼: | >>参与讨论 |
作者: hswqs 于 2006/12/27 15:19:00 发布:
xwj,能用汇编优化当然最好,可惜偶功力不足啊 |
12楼: | >>参与讨论 |
作者: 农民讲习所 于 2006/12/27 15:20:00 发布:
: union VarStruct{ unsigned LONG mLong; unsigned int mInt[2]; unsigned CHAR mChar[4]; }; unsigned int CHECKSUM(unsigned int xdata *check,unsigned int length) { //计算校验和 union VarStruct sum; unsigned int i; sum.mLong = 0; i = length/2; while( i-- ) { sum.mLong += *check++; } if(length&0x01)//表示长度为单数 { sum.mLong += (unsigned CHAR)(*check); } sum.mLong = sum.mInt[0] + sum.mInt[1];//高16位和低16位相加 if(sum.mChar[1] ) //51是高位在前。 {//表示有进位 sum.mInt[1] ++; } return sum.mInt[1]; } * - 本贴最后修改时间:2006-12-27 15:27:54 修改者:农民讲习所 |
13楼: | >>参与讨论 |
作者: tj_zhaozq 于 2006/12/30 16:08:00 发布:
我在楼上的基础上再来优化一下 如果length可以最大小于512的话 unsigned CHAR i; i = (unsigned CHAR)(length/2); do { sum.mLong += *check++; }while(--i); 这个方面很有效果; * - 本贴最后修改时间:2006-12-30 16:32:36 修改者:tj_zhaozq |
14楼: | >>参与讨论 |
作者: sharks 于 2006/12/30 16:12:00 发布:
用自动产生CRC的网络芯片,如CP2200 |
15楼: | >>参与讨论 |
作者: xwj 于 2006/12/30 16:30:00 发布:
27号就试好了,用汇编可以快3倍 看到没人关注我也就懒得发了 所长的代码有错误,结果不对哦 //这是TCP/IP协议中的校验和计算代码,使用中反复调用,KEIL C51编译后的汇编指令一大堆, //谁能帮忙做个优化,汇编也行,不甚感激! extern unsigned int CHECKSUM(unsigned int xdata *check,unsigned int length); extern unsigned int CHECKSUMx(unsigned int xdata *check,unsigned int length); /********************************************/ unsigned int CHECKSUM1(unsigned int xdata *check,unsigned int length) { //计算校验和 unsigned LONG data sum =0; unsigned int data i; for (i=0;i<(length)/2;i++) { sum+=*check++; } if(length&0x01)//表示长度为单数 { sum=sum+((*check)&0xff00); } sum=(sum&0xffff)+((sum>>16)&0xffff);//高16位和低16位相加 if(sum&0xffff0000) {//表示有进位 sum++; } return ( (unsigned int)(~((sum)&0xffff)) ); } /********************************************/ union Varstruct{ unsigned LONG mLONG; unsigned int mInt[2]; unsigned CHAR mCHAR[4]; }; unsigned int CHECKSUM2(unsigned int xdata *check,unsigned int length) { //计算校验和 union Varstruct sum; unsigned int i; sum.mLONG = 0; i = length/2; do { sum.mLONG += *check++; } while( --i ); if(length&0x01)//表示长度为单数 { sum.mLONG +=((*check)&0xff00); } sum.mLONG = sum.mInt[0] + sum.mInt[1];//高16位和低16位相加 if(sum.mCHAR[0] ) //51是高位在前。 {//表示有进位 sum.mInt[1] ++; } return ~(sum.mInt[1]); } /********************************************/ void main(void) { unsigned int xdata *check; unsigned int sum,i; check=0; for (i=0;i<10000.html">10000;i++) { *check++ = -i; } while(1) { sum=CHECKSUM(10,1000); //11531 sum=CHECKSUMx(10,1000); //9301 sum=CHECKSUM1(10,1000); //27347 sum=CHECKSUM2(10,1000); //21554 sum=CHECKSUM(20,1001); //11542 sum=CHECKSUMx(20,1001); //9292 sum=CHECKSUM1(20,1001); //27370 sum=CHECKSUM2(20,1001); //21573 sum=CHECKSUM(2000,100); //1181 sum=CHECKSUMx(2000,100); //964 sum=CHECKSUM1(2000,100); //3046 |
16楼: | >>参与讨论 |
作者: xwj 于 2006/12/30 16:35:00 发布:
... * - 本贴最后修改时间:2006-12-31 21:37:39 修改者:xwj |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |