title: Dividing / Shifting Assembly Differences
body: <p>Good morning, afternoon or night,</p>
  
  <p>Having been looking at assembly code of a debug build with "Suppress JIT optimization (...)" option turned off, I have noticed the following strange behaviour (<code>bitCount</code> is <code>ulong</code>):</p>
  
  <pre><code>          int BitQuotient = (int)(bitCount / 32);
  
  00000110  push        dword ptr [ebp+0Ch] 
  00000113  push        dword ptr [ebp+8] 
  00000116  push        0 
  00000118  push        20h 
  0000011a  call        738EF4D5 
  0000011f  mov         dword ptr [ebp-44h],eax 
  </code></pre>
  
  <p>as opposed to</p>
  
  <pre><code>          int BitQuotient = (int)(bitCount &gt;&gt; 5);
  
  00000110  mov         eax,dword ptr [ebp+8] 
  00000113  mov         edx,dword ptr [ebp+0Ch] 
  00000116  shrd        eax,edx,5 
  0000011a  shr         edx,5 
  0000011d  mov         dword ptr [ebp-44h],eax 
  </code></pre>
  
  <p>Why is there such a difference in assembly? Shouldn't the compiler detect that dividing by 32 is the same as shifting right by 5 and replace the code? Also, what is that <code>call</code> instruction doing on the first piece of code? I suspect it has to do with the operator <code>/</code> being applied to non-native <code>ulong</code>, but that also means the compiler doesn't inline this kind of operators?</p>
  
  <p><strong>Edit:</strong> Have a look at <code>int BitRemainder = (int)(bitCount % 32)</code> as opposed to <code>int BitRemainder = (int)(bitCount &amp; 31)</code>:</p>
  
  <pre><code>00000120  mov         eax,dword ptr [ebp+8] 
  00000123  mov         edx,dword ptr [ebp+0Ch] 
  00000126  mov         ecx,20h 
  0000012b  cmp         edx,ecx 
  0000012d  jb          00000139 
  0000012f  mov         ebx,eax 
  00000131  mov         eax,edx 
  00000133  xor         edx,edx 
  00000135  div         eax,ecx 
  00000137  mov         eax,ebx 
  00000139  div         eax,ecx 
  0000013b  mov         eax,edx 
  0000013d  xor         edx,edx 
  0000013f  mov         dword ptr [ebp-48h],eax 
  </code></pre>
  
  <p>and</p>
  
  <pre><code>00000120  mov         eax,dword ptr [ebp+8] 
  00000123  and         eax,1Fh 
  00000126  mov         dword ptr [ebp-48h],eax 
  </code></pre>
  
  <p>Thank you very much.</p>