Advertisement
Guest User

CRC32 asm to c-sharp

a guest
Oct 15th, 2012
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.30 KB | None | 0 0
  1. Explaining my answer of question http://stackoverflow.com/q/12876436/1152602 .
  2.  
  3. First, I assume you have at least a basic understanding of assembly language, register, flags, and binary arithmetic (masks, OR, XOR, all that stuff). If not, take a look at this wikibook: en.wikibooks.org/wiki/X86_Assembly . It is incomplete, but was a great reference for me while I was learning assembly. Also, I used this link to understand how delphi assembler works, and what were the conventions for parameters/return values: http://www.tek-tips.com/faqs.cfm?fid=7412 . Also I needed x86 instruction reference from Intel http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html , more precisely volumes 2A, 2B and 2C. They contain detailed instruction reference, saying what it exactly does, what flags are after the operation, etc.
  4.  
  5. Now for commented C# code.
  6. There was some guesswork, I marked them with " // G! " so if you don't understand
  7. these steps, don't worry, I didn't understand them too =)
  8.  
  9.  
  10. static uint CRC32(uint CRC, byte[] data)
  11. {
  12. // The original parameters where: CRC, Data and DataSize.
  13. // Delphi conventions are: first parameter in EAX, second in EDX, third in ECX.
  14. // The return value must be stored in EAX.
  15.  
  16. // This first IF represents lines
  17. // AND EDX,EDX
  18. // JZ @Exit
  19. // AND ECX,ECX
  20. // JLE @Exit
  21. // Basically an AND with itself does nothing to the number, but sets the
  22. // flags according to it.
  23. // JZ means "Jump if zero". So, if EDX (the Data pointer) equals zero (null) then the function
  24. // quits.
  25. // The returned value is EAX, so, EAX is the first parameter, we just return CRC.
  26. // JLE means "Jump if less or equal". Intel reference says this means it will jump if
  27. // the zero flag is true (== 0),
  28. // or if the sign flag is true. (negative number).
  29. // ECX is the third parameter (DataSize), so here I use it with data.Length.
  30. // It really should be "data.Length > 0", but as Length property is never negative,
  31. // it does not matter here.
  32. if (data == null || data.Length == 0) return CRC;
  33.  
  34. // Here I declare variables with the same name as registers,
  35. // and corresponding values.
  36. // This represents lines
  37. // PUSH EBX
  38. // PUSH EDI
  39. // XOR EBX,EBX
  40. // LEA EDI,CS:[OFFSET @CRC32]
  41. // PUSH EBX and PUSH EDI stores EBX's and EDI's values to the stack.
  42. // Delphi conventions says EBX and EDI values must be preserved.
  43. // We will need to use these register so we store the values in the stack,
  44. // after execution of the function we will restore the original values.
  45. // XOR of a number with itself will zero it out, so XOR EBX,EBX means "EBX = 0"
  46. // LEA gets the address of the second operand and stores it in the first operand.
  47. // So the instruction is getting the address of the table and storing it in EDI. // G!
  48. // Here this address is represented as the static field "Table" below...
  49. uint eax = CRC, ebx = 0, ecx = (uint)data.Length, edx = 0;
  50.  
  51. // The label, @Start ..
  52. Start:
  53.  
  54. // This is MOV BL,AL.
  55. // BL means the lower 16-bits of EBX,
  56. // AL means the lower 16-bits of EAX.
  57. // So I get the lower 16-bits of eax by doing an AND with the mask 0x0000FFFF,
  58. // erase the lower 16-bits of ebx with the mask 0xFFFF0000, and combine the two with OR.
  59. ebx = (ebx & 0xFFFF0000) | (eax & 0x0000FFFF);
  60.  
  61. // SHR EAX, 8 -- shifts eax right by 8 bits, pretty obvious =)
  62. eax >>= 8;
  63.  
  64. // This represents instruction
  65. // XOR BL,[EDX]
  66. // First I get the value pointed by EDX (corresponds to the Data parameter)
  67. // and XOR it with the lower 16-bit of EBX.
  68. // But as [EDX] is an expression of 8-bit size,
  69. // the result of the operation must also be of size 8-bit. // G!
  70. // so I mask EBX with 0x000000FF to discard all the bits except the last 8-bits.
  71. // Then I proceed like I did above: erase the last 16-bits of EBX and
  72. // combine EBX with the result of the [EDX] expression.
  73. ebx = (ebx & 0xFFFF0000) | (data[edx] ^ (ebx & 0x000000FF));
  74.  
  75. // This represents
  76. // XOR EAX,[EDI + EBX * 4]
  77. // EDI points to the start of the table. Adding EBX * 4 to it means
  78. // that we are accessing 32-bit at a time (4*8 = 32).
  79. // The table is an array of unsigned ints (uint / UInt32), already 32 bits, so
  80. // in C# the multiplication by 4 is unnecessary, I just get the element in EBX position.
  81. eax = eax ^ Table[ebx];
  82.  
  83. // The following lines are
  84. // INC EDX
  85. // DEC ECX
  86. // Pretty obvious =)
  87. edx++;
  88. ecx--;
  89.  
  90. // This represents
  91. // JNZ @Start
  92. // The last operation ("DEC ECX") also sets the flags according to ECX.
  93. // So if ECX is not zero it will jump to Start.
  94. if (ecx != 0) goto Start;
  95.  
  96. // The following instructions
  97. // POP EDI
  98. // POP EBX
  99. // restores the original values of these two registers, as explained above.
  100. // Not needed in the C# translation.
  101.  
  102. // EAX is the return value of the function.
  103. return eax;
  104.  
  105.  
  106. // Explanation fueled by some bottles of Heineken =)
  107. }
  108.  
  109.  
  110. // And the table
  111. static readonly uint[] Table = {
  112. 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
  113. 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
  114. 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
  115. 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
  116. 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
  117. 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
  118. 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
  119. 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
  120. 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
  121. 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
  122. 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
  123. 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
  124. 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
  125. 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
  126. 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
  127. 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
  128. 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
  129. 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
  130. 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
  131. 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
  132. 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
  133. 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
  134. 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
  135. 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
  136. 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
  137. 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
  138. 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
  139. 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
  140. 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
  141. 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
  142. 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
  143. 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
  144. 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
  145. 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
  146. 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
  147. 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
  148. 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
  149. 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
  150. 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
  151. 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
  152. 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
  153. 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
  154. 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
  155. 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
  156. 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
  157. 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
  158. 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
  159. 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
  160. 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
  161. 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
  162. 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
  163. 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
  164. 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
  165. 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
  166. 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
  167. 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
  168. 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
  169. 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
  170. 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
  171. 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
  172. 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
  173. 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
  174. 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
  175. 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
  176. 0x74726F50, 0x736E6F69, 0x706F4320, 0x67697279,
  177. 0x28207468, 0x31202963, 0x20393939, 0x48207962,
  178. 0x6E656761, 0x64655220, 0x6E616D64, 0x6FBBA36E };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement