⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sum386.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/* sum186.c

   Copyright 2000 by InterNIche Technologies Inc. All rights reserved.
   Copyright 1990-1996 by NetPort Software.

*/

#include "ipport.h"

/* cksum(buf, len) performs an Internet type checksum. buf points to where
 	the checksumming should begin, len is the number of 16 bit words
	to be summed.

   This version for intel x86 CPUs in 16 bit mode (i.e. DOS)
*/

extern unshort cksum1(u_char * buf, int len);

unshort
cksum(u_char * buf, int len)
{
unshort sum;

//   return(cksum1(buf, len));

   _asm { mov  esi, buf };    /* load address of buffer to sum */
   _asm { mov	ecx, len };    /* get word count after seg:offset */

   _asm { mov	eax, ecx	 };   /* copy of word count  */
   _asm { and	ecx, 0FFFFFFE0h };   /* mask count for div/32 */
   _asm { and	eax, 01eh };   /*  get remainder of count %32, masking odd word */
   _asm { shl  eax, 1  };     /* make it a byte count */
   _asm { mov	ebx, 64 };     /* make inverse of (64-remainder) */
   _asm { sub	ebx, eax };    /* 64 - count%64 in BX */
   _asm { sub  esi, ebx };    /* adjust pointer for table offsets */
   _asm { sub  esi, 4 };      /* adjust for table starting with offset 4 */

   _asm { mov	eax, ebx };    /* copy of offset into ax */
   _asm { add  eax, ebx };    /* times 2... */
   _asm { add  eax, ebx };    /* times 3 bytes per table opcode */
   _asm { shr  eax, 2 };      /* divide for dwords => sum64 table index */
   _asm { add  eax, offset sum64 } ; /* add to start */

   _asm { mov  edx, len };    /* get word count into DX */
   _asm { and  edx, 1 };      /* make odd-word flag in DX */

   _asm { push eax };         /* put jump address on stack */
   _asm { mov  ebx, esp };    /* ss:ebx now points to jump offset */

   _asm { xor	eax, eax	};    /*  initial value for xsum, clear carry */
   _asm { jmp	dword ptr ss:[ebx] };


sum64:
   /* start with offset of 4 instead of 0 so all opcodes are same size */
   _asm { adc	eax, dword ptr [ESI + 4] };
   _asm { adc	eax, dword ptr [ESI + 8] };
   _asm { adc	eax, dword ptr [ESI + 12] };
   _asm { adc	eax, dword ptr [ESI + 16] };
   _asm { adc	eax, dword ptr [ESI + 20] };
   _asm { adc	eax, dword ptr [ESI + 24] };
   _asm { adc	eax, dword ptr [ESI + 28] };
   _asm { adc	eax, dword ptr [ESI + 32] };
   _asm { adc	eax, dword ptr [ESI + 36] };
   _asm { adc	eax, dword ptr [ESI + 40] };
   _asm { adc	eax, dword ptr [ESI + 44] };
   _asm { adc	eax, dword ptr [ESI + 48] };
   _asm { adc	eax, dword ptr [ESI + 52] };
   _asm { adc	eax, dword ptr [ESI + 56] };
   _asm { adc	eax, dword ptr [ESI + 60] };
   _asm { adc	eax, dword ptr [ESI + 64] };

   _asm { adc  eax, 0 }       /* don't drop last carry */

   _asm { jcxz fold_halfword };  /* done with all halfwords? */

   _asm { pushf };            /* save carry flag */
   _asm { sub	ecx, 32 };     /* drop word count */
   _asm { add  esi, 64 };     /* bump byte pointer */
   _asm { popf };             /* restore carry flag */
   _asm { jmp	sum64 };       /* back for next 64 bytes */

add_halfword:
   _asm { mov  ecx, [ESI + 68] };/* get next word */
   _asm { and  ecx, 0000FFFFh }; /* mask down to first halfword */
   _asm { adc	eax, ecx };       /* add last word */
   _asm { xor  dx,dx };          /* clear odd (half)word flag */

fold_halfword:
   _asm { cmp  edx, 1 };         /* one odd halfword all thats left? */
   _asm { je   add_halfword };   /* go handle odd halfword */
   _asm { mov  ecx, eax };       /* duplicate 32 bit sum */
   _asm { and  ecx, 0000FFFFh }; /* mask to lower 16 bits */
   _asm { rol  eax, 16 };        /* get upper 16 bits in low reg. */
   _asm { and  eax, 0000FFFFh }; /* mask to lower 16 bits */
   _asm { add  ax, cx };         /* add two 16 bit values */
   _asm { adc  ax, 0 };          /* add carry bit */
   _asm { adc  ax, 0 };          /* add carry bit */

   _asm { pop  ebx };       /* even out stack frame */
   _asm { mov  sum, ax };

#ifdef NOTDEF
{unshort sum2; /* tmp debug section */
   sum2 = cksum1(buf, len);

   if(sum != sum2)
   {
      Printu_Net ( "sum bug; right: %x, wrong: %x\n", sum2, sum );
      sum = sum2;
   }
}
#endif

   return sum;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -