Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The whole thing</p> <pre><code>00401010 |&gt; 99 /CDQ 00401011 |. 2BC2 |SUB EAX,EDX 00401013 |. D1F8 |SAR EAX,1 </code></pre> <p>stands for the <code>y /= 2</code>. You see, a standalone <code>SAR</code> would not perform the signed integer division the way the compiler authors intended. C++98 standard <em>recommends</em> that signed integer division rounds the result towards 0, while <code>SAR</code> alone would round towards the negative infinity. (It is permissible to round towards negative infinity, the choice is left to the implementation). In order to implement rounding to 0 for negative operands, the above trick is used. If you use an unsigned type instead of a signed one, then the compiler will generate just a single shift instruction, since the issue with negative division will not take place.</p> <p>The trick is pretty simple: for negative <code>y</code> sign extension will place a pattern of <code>11111...1</code> in <code>EDX</code>, which is actually <code>-1</code> in 2's complement representation. The following <code>SUB</code> will effectively add 1 to <code>EAX</code> if the original <code>y</code> value was negative. If the original <code>y</code> was positive (or 0), the <code>EDX</code> will hold <code>0</code> after the sign extension and <code>EAX</code> will remain unchanged. </p> <p>In other words, when you write <code>y /= 2</code> with signed <code>y</code>, the compiler generates the code that does something more like the following</p> <pre><code>y = (y &lt; 0 ? y + 1 : y) &gt;&gt; 1; </code></pre> <p>or, better</p> <pre><code>y = (y + (y &lt; 0)) &gt;&gt; 1; </code></pre> <p>Note, that C++ standard does not require the result of the division to be rounded towards zero, so the compiler has the right to do just a single shift even for signed types. However, normally compilers follow the <em>recommendation</em> to round towards zero (or offer an option to control the behavior).</p> <p><strong>P.S.</strong> I don't know for sure what the purpose of that <code>LEA</code> instruction is. It is indeed a no-op. However, I suspect that this might be just a placeholder instruction inserted into the code for further patching. If I remember correctly, MS compiler has an option that forces the insertion of placeholder instructions at the beginning and at the end of each function. In the future this instruction can be <em>overwritten</em> by the patcher with a <code>CALL</code> or <code>JMP</code> instruction that will execute the patch code. This specific <code>LEA</code> was chosen just because it produces the a no-op placeholder instruction of the correct length. Of course, it could be something completely different.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload