Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
8.2 KiB

4 years ago
  1. title "Compute Checksum"
  2. ;/*++
  3. ;
  4. ; Copyright (c) 1992 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; chksum.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements a fucntion to compute the checksum of a buffer.
  13. ;
  14. ; Author:
  15. ;
  16. ; David N. Cutler (davec) 27-Jan-1992
  17. ;
  18. ; Environment:
  19. ;
  20. ; Any mode.
  21. ;
  22. ; Revision History:
  23. ;
  24. ;--*/
  25. .386
  26. .model small,c
  27. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  28. assume fs:nothing,gs:nothing
  29. .xlist
  30. include callconv.inc
  31. include ks386.inc
  32. .list
  33. .code
  34. ;++
  35. ;
  36. ; USHORT
  37. ; ChkSum(
  38. ; IN ULONG cksum,
  39. ; IN PUSHORT buf,
  40. ; IN ULONG len
  41. ; )
  42. ;
  43. ; Routine Description:
  44. ;
  45. ; This function computes the checksum of the specified buffer.
  46. ;
  47. ; Arguments:
  48. ;
  49. ; cksum - Suppiles the initial checksum value.
  50. ;
  51. ; buf - Supplies a pointer to the buffer that is checksumed.
  52. ;
  53. ; len - Supplies the of the buffer in words.
  54. ;
  55. ; Return Value:
  56. ;
  57. ; The computed checksum is returned as the function value.
  58. ;
  59. ;--
  60. cksum equ 8 ; stack offset to initial checksum
  61. buf equ 12 ; stack offset to source address
  62. len equ 16 ; stack offset to length in words
  63. cPublicProc ChkSum,3
  64. push esi ; save nonvolatile register
  65. mov ecx,[esp + len] ; get length in words
  66. mov esi,[esp + buf] ; get source address
  67. mov eax,[esp + cksum] ; get initial checksum
  68. shl ecx,1 ; convert to length in bytes
  69. jz cks80 ; if z set, no words to checksum
  70. ;
  71. ; Compute checksum in cascading order of block size until 128 byte blocks
  72. ; are all that is left, then loop on 128-bute blocks.
  73. ;
  74. test esi,02h ; check if source dword aligned
  75. jz short cks10 ; if z set, source is dword aligned
  76. sub edx,edx ; get initial word for alignment
  77. mov dx,[esi + 0] ;
  78. add eax,edx ; update partial checkcum
  79. adc eax,0 ; add carry
  80. add esi,2 ; update source address
  81. sub ecx,2 ; reduce length in bytes
  82. cks10: mov edx,ecx ; isolate residual bytes
  83. and edx,07h ;
  84. sub ecx,edx ; subtract residual bytes
  85. jz cks60 ; if z set, no 8-byte blocks
  86. test ecx,08h ; test if initial 8-byte block
  87. jz short cks20 ; if z set, no initial 8-byte block
  88. add eax,[esi + 0] ; compute 8-byte checksum
  89. adc eax,[esi + 4] ;
  90. adc eax,0 ; add carry
  91. add esi,8 ; update source address
  92. sub ecx,8 ; reduce length of checksum
  93. jz cks60 ; if z set, end of 8-byte blocks
  94. cks20: test ecx,010h ; test if initial 16-byte block
  95. jz short cks30 ; if z set, no initial 16-byte block
  96. add eax,[esi + 0] ; compute 16-byte checksum
  97. adc eax,[esi + 4] ;
  98. adc eax,[esi + 8] ;
  99. adc eax,[esi + 12] ;
  100. adc eax,0 ; add carry
  101. add esi,16 ; update source address
  102. sub ecx,16 ; reduce length of checksum
  103. jz cks60 ; if z set, end of 8-byte blocks
  104. cks30: test ecx,020h ; test if initial 32-byte block
  105. jz short cks40 ; if z set, no initial 32-byte block
  106. add eax,[esi + 0] ; compute 32-byte checksum
  107. adc eax,[esi + 4] ;
  108. adc eax,[esi + 8] ;
  109. adc eax,[esi + 12] ;
  110. adc eax,[esi + 16] ;
  111. adc eax,[esi + 20] ;
  112. adc eax,[esi + 24] ;
  113. adc eax,[esi + 28] ;
  114. adc eax,0 ; add carry
  115. add esi,32 ; update source address
  116. sub ecx,32 ; reduce length of checksum
  117. jz cks60 ; if z set, end of 8-byte blocks
  118. cks40: test ecx,040h ; test if initial 64-byte block
  119. jz cks50 ; if z set, no initial 64-byte block
  120. add eax,[esi + 0] ; compute 64-byte checksum
  121. adc eax,[esi + 4] ;
  122. adc eax,[esi + 8] ;
  123. adc eax,[esi + 12] ;
  124. adc eax,[esi + 16] ;
  125. adc eax,[esi + 20] ;
  126. adc eax,[esi + 24] ;
  127. adc eax,[esi + 28] ;
  128. adc eax,[esi + 32] ;
  129. adc eax,[esi + 36] ;
  130. adc eax,[esi + 40] ;
  131. adc eax,[esi + 44] ;
  132. adc eax,[esi + 48] ;
  133. adc eax,[esi + 52] ;
  134. adc eax,[esi + 56] ;
  135. adc eax,[esi + 60] ;
  136. adc eax,0 ; add carry
  137. add esi,64 ; update source address
  138. sub ecx,64 ; reduce length of checksum
  139. jz short cks60 ; if z set, end of 8-byte blocks
  140. cks50: add eax,[esi + 0] ; compute 64-byte checksum
  141. adc eax,[esi + 4] ;
  142. adc eax,[esi + 8] ;
  143. adc eax,[esi + 12] ;
  144. adc eax,[esi + 16] ;
  145. adc eax,[esi + 20] ;
  146. adc eax,[esi + 24] ;
  147. adc eax,[esi + 28] ;
  148. adc eax,[esi + 32] ;
  149. adc eax,[esi + 36] ;
  150. adc eax,[esi + 40] ;
  151. adc eax,[esi + 44] ;
  152. adc eax,[esi + 48] ;
  153. adc eax,[esi + 52] ;
  154. adc eax,[esi + 56] ;
  155. adc eax,[esi + 60] ;
  156. adc eax,[esi + 64] ;
  157. adc eax,[esi + 68] ;
  158. adc eax,[esi + 72] ;
  159. adc eax,[esi + 76] ;
  160. adc eax,[esi + 80] ;
  161. adc eax,[esi + 84] ;
  162. adc eax,[esi + 88] ;
  163. adc eax,[esi + 92] ;
  164. adc eax,[esi + 96] ;
  165. adc eax,[esi + 100] ;
  166. adc eax,[esi + 104] ;
  167. adc eax,[esi + 108] ;
  168. adc eax,[esi + 112] ;
  169. adc eax,[esi + 116] ;
  170. adc eax,[esi + 120] ;
  171. adc eax,[esi + 124] ;
  172. adc eax,0 ; add carry
  173. add esi,128 ; update source address
  174. sub ecx,128 ; reduce length of checksum
  175. jnz short cks50 ; if z clear, not end of 8-byte blocks
  176. ;
  177. ; Compute checksum on 2-byte blocks.
  178. ;
  179. cks60: test edx,edx ; check if any 2-byte blocks
  180. jz short cks80 ; if z set, no 2-byte blocks
  181. cks70: sub ecx,ecx ; load 2-byte block
  182. mov cx,[esi + 0] ;
  183. add eax,ecx ; compue 2-byte checksum
  184. adc eax,0 ;
  185. add esi,2 ; update source address
  186. sub edx,2 ; reduce length of checksum
  187. jnz short cks70 ; if z clear, more 2-bytes blocks
  188. ;
  189. ; Fold 32-but checksum into 16-bits
  190. ;
  191. cks80: mov edx,eax ; copy checksum value
  192. shr edx,16 ; isolate high order bits
  193. and eax,0ffffh ; isolate low order bits
  194. add eax,edx ; sum high and low order bits
  195. mov edx,eax ; isolate possible carry
  196. shr edx,16 ;
  197. add eax,edx ; add carry
  198. and eax,0ffffh ; clear possible carry bit
  199. pop esi ; restore nonvolatile register
  200. stdRET ChkSum
  201. stdENDP ChkSum
  202. end
  203.