Deduped images
This commit is contained in:
parent
4eef8b2919
commit
9e52de9586
233 changed files with 128 additions and 128 deletions
|
|
@ -79,11 +79,11 @@ BIT_PATTERN=BIT_PATTERN SHL 1
|
|||
</PRE>
|
||||
<!-- END CODE SNIP //-->
|
||||
<TABLE WIDTH="100%">
|
||||
<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/07-06i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Besides illustrating the advantages of local optimization, this example also shows that it generally pays to precalculate results; this is often done at or before assembly time, but precalculated tables can also be built at run time. This is merely one aspect of a fundamental optimization rule: Move as much work as possible out of your critical code by whatever means necessary.</I></SMALL>
|
||||
<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Besides illustrating the advantages of local optimization, this example also shows that it generally pays to precalculate results; this is often done at or before assembly time, but precalculated tables can also be built at run time. This is merely one aspect of a fundamental optimization rule: Move as much work as possible out of your critical code by whatever means necessary.</I></SMALL>
|
||||
</TABLE>
|
||||
<H4 ALIGN="LEFT"><A NAME="Heading9"></A><FONT COLOR="#000077">NOT Flips Bits—Not Flags</FONT></H4>
|
||||
<P>The <B>NOT</B> instruction flips all the bits in the operand, from 0 to 1 or from 1 to 0. That’s as simple as could be, but <B>NOT</B> nonetheless has a minor but interesting talent: It doesn’t affect the flags. That can be irritating; I once spent a good hour tracking down a bug caused by my unconscious assumption that <B>NOT</B> does set the flags. After all, every other arithmetic and logical instruction sets the flags; why not <B>NOT</B>? Probably because <B>NOT</B> isn’t considered to be an arithmetic or logical instruction at all; rather, it’s a data manipulation instruction, like <B>MOV</B> and the various rotates. (These are <B>RCR, RCL, ROR,</B> and <B>ROL,</B> which affect only the Carry and Overflow flags.) NOT is often used for tasks, such as flipping masks, where there’s no reason to test the state of the result, and in that context it can be handy to keep the flags unmodified for later testing.</P>
|
||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/07-07i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Besides, if you want to <B>NOT</B> an operand and set the flags in the process, you can just <B>XOR</B> it with -1. Put another way, the only functional difference between <B>NOT AX</B> and <B>XOR AX,0FFFFH</B> is that <B>XOR</B> modifies the flags and <B>NOT</B> doesn’t.</I></SMALL>
|
||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Besides, if you want to <B>NOT</B> an operand and set the flags in the process, you can just <B>XOR</B> it with -1. Put another way, the only functional difference between <B>NOT AX</B> and <B>XOR AX,0FFFFH</B> is that <B>XOR</B> modifies the flags and <B>NOT</B> doesn’t.</I></SMALL>
|
||||
</TABLE>
|
||||
<P>The x86 instruction set offers many ways to accomplish almost any task. Understanding the subtle distinctions between the instructions—whether and which flags are set, for example—can be critical when you’re trying to optimize a code sequence and you’re running out of registers, or when you’re trying to minimize branching.
|
||||
</P>
|
||||
|
|
@ -121,7 +121,7 @@ LOOP_TOP:
|
|||
<!-- END CODE //-->
|
||||
<P>It’s not that the Listing 7.6 approach is necessarily better or worse; that depends on the processor and the situation. The Listing 7.6 approach is <I>different,</I> and if you understand the differences, you’ll be able to choose the best approach for whatever code you happen to write. (<B>DEC</B> has the same property of preserving the Carry flag, by the way.)</P>
|
||||
<P>There are a couple of interesting aspects to the last example. First, note that <B>LOOP</B> doesn’t affect any flags at all; this allows the Carry flag to remain unchanged from one addition to the next. Not altering the arithmetic flags is a common characteristic of program control instructions (as opposed to arithmetic and logical instructions like <B>SUB</B> and <B>AND,</B> which do alter the flags).</P>
|
||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/07-08i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>The rule is not that the arithmetic flags change whenever the CPU performs a calculation; rather, the flags change whenever you execute an arithmetic, logical, or flag control (such as <B>CLC</B> to clear the Carry flag) instruction.</I></SMALL>
|
||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>The rule is not that the arithmetic flags change whenever the CPU performs a calculation; rather, the flags change whenever you execute an arithmetic, logical, or flag control (such as <B>CLC</B> to clear the Carry flag) instruction.</I></SMALL>
|
||||
</TABLE>
|
||||
<P>Not only do <B>LOOP</B> and <B>JCXZ</B> not alter the flags, but <B>REP MOVS</B>, which counts down CX to 0, doesn’t affect the flags either.</P>
|
||||
<P>The other interesting point about the last example is the use of <B>LAHF</B> and <B>SAHF,</B> which transfer the low byte of the FLAGS register to and from AH, respectively. These instructions were created to help provide compatibility with the 8080’s (that’s <I>8080</I>, not <I>8088</I>) <B>PUSH</B> <B>PSW</B> and <B>POP PSW</B> instructions, but turn out to be compact (one byte) instructions for saving and restoring the arithmetic flags. A word of caution, however: <B>SAHF</B> restores the Carry, Zero, Sign, Auxiliary Carry, and Parity flags—but <I>not</I> the Overflow flag, which resides in the high byte of the FLAGS register. Also, be aware that <B>LAHF</B> and <B>SAHF</B> provide a fast way to preserve the flags on an 8088 but are relatively slow instructions on the 486 and Pentium.</P>
|
||||
|
|
|
|||
Loading…
Reference in a new issue