📄 sum386.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 + -