/* oneC_sum() - One complement`s checksum Author: Kees J. Bot */ /* 9 May 1995 */ /* See RFC 1071, "Computing the Internet checksum" */ /* See also the C version of this code. */ #include ENTRY(oneC_sum) push %ebp movl %esp, %ebp push %esi push %edi movzwl 8(%ebp), %eax /* Checksum of previous block */ movl 12(%ebp), %esi /* Data to compute checksum over */ movl 16(%ebp), %edi /* Number of bytes */ xorl %edx, %edx xorb %cl, %cl align: testl $3, %esi /* Is the data aligned? */ je aligned testl %edi, %edi je 0f movb (%esi), %dl /* Rotate the first unaligned bytes */ decl %edi /* into the edx register */ 0: incl %esi rorl $8, %edx rorl $8, %eax /* Rotate the checksum likewise */ addb $8, %cl /* Number of bits rotated */ jmp align aligned: addl %edx, %eax /* Summate the unaligned bytes */ adcl $0, %eax /* Add carry back in for one`s complement */ jmp add6test _ALIGN_TEXT add6: addl (%esi), %eax /* Six times unrolled loop, see below */ adcl 4(%esi), %eax adcl 8(%esi), %eax adcl 12(%esi), %eax adcl 16(%esi), %eax adcl 20(%esi), %eax adcl $0, %eax addl $24, %esi add6test: subl $24, %edi jae add6 addl $24, %edi jmp add1test _ALIGN_TEXT add1: addl (%esi), %eax /* while ((edi -= 4) >= 0) */ adcl $0, %eax /* eax += *esi++; */ addl $4, %esi /* edi += 4; */ add1test: subl $4, %edi jae add1 addl $4, %edi je done /* Are there extra bytes? */ movl (%esi), %edx /* Load extra bytes in a full dword */ andl mask-4(,%edi,4), %edx /* Mask off excess */ addl %edx, %eax /* Add in the last bits */ adcl $0, %eax done: roll %cl, %eax /* Undo the rotation at the beginning */ movl %eax, %edx shrl $16, %eax addw %dx, %ax /* Add the two words in eax to form */ adcw $0, %ax /* a 16 bit sum */ pop %edi pop %esi pop %ebp ret #ifdef __ACK__ .rom #else .data #endif .balign 4 mask: .long 0x000000FF, 0x0000FFFF, 0x00FFFFFF /* */ /* $PchId: oneC_sum.ack.s,v 1.2 1996/03/12 19:33:51 philip Exp $ */