Deduped images

This commit is contained in:
James Gregory 2013-12-30 12:25:34 +11:00
commit 9e52de9586
233 changed files with 128 additions and 128 deletions

View file

@ -50,7 +50,7 @@
<P>An encyclopedic approach to 486 optimization would take a book all by itself, so in this chapter I&#146;m only going to hit the highlights of 486 optimization, touching on several optimization rules, some documented, some not. You might also want to check out the following sources of 486 information: <I>i486 Microprocessor Programmer&#146;s Reference Manual,</I> from Intel; &#147;8086 Optimization: Aim Down the Middle and Pray,&#148; in the March, 1991 <I>Dr. Dobb&#146;s Journal</I>; and &#147;Peak Performance: On to the 486,&#148; in the November, 1990 <I>Programmer&#146;s Journal.</I></P>
<H3><A NAME="Heading4"></A><FONT COLOR="#000077">Rules to Optimize By</FONT></H3>
<P>In Appendix G of the <I>i486 Microprocessor Programmer</I>&#146;<I>s</I> <I>Reference Manual</I>, Intel lists a number of optimization techniques for the 486. While neither exhaustive (we&#146;ll look at two undocumented optimizations shortly) nor entirely accurate (we&#146;ll correct two of the rules here), Intel&#146;s list is certainly a good starting point. In particular, the list conveys the extent to which 486 optimization differs from optimization for earlier x86 processors. Generally, I&#146;ll be discussing optimization for real mode (it being the most widely used mode at the moment), although many of the rules should apply to protected mode as well.</P>
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/12-01i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>486 optimization is generally more precise and less frustrating than optimization for other x86 processors because every 486 has an identical internal cache. Whenever both the instructions being executed and the data the instructions access are in the cache, those instructions will run in a consistent and calculatable number of cycles on all 486s, with little chance of interference from the prefetch queue and without regard to the speed of external memory.</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>486 optimization is generally more precise and less frustrating than optimization for other x86 processors because every 486 has an identical internal cache. Whenever both the instructions being executed and the data the instructions access are in the cache, those instructions will run in a consistent and calculatable number of cycles on all 486s, with little chance of interference from the prefetch queue and without regard to the speed of external memory.</I></SMALL>
</TABLE>
<P>In other words, for cached code (which time-critical code almost always is), performance is predictable and can be calculated with good precision, and those calculations will apply on any 486. However, &#147;predictable&#148; doesn&#146;t mean &#147;trivial&#148;; the cycle times printed for the various instructions are not the whole story. You must be aware of all the rules, documented and undocumented, that go into calculating actual execution times&#151;and uncovering some of those rules is exactly what this chapter is about.
</P>
@ -59,7 +59,7 @@
</P>
<P>Intel cautions against using indexing to address memory because there&#146;s a one-cycle penalty for indexed addressing. True enough&#151;but &#147;indexed addressing&#148; might not mean what you expect.</P>
<P>Traditionally, SI and DI are considered the index registers of the x86 CPUs. That is not the sense in which &#147;indexed addressing&#148; is meant here, however. In real mode, indexed addressing means that two registers, rather than one or none, are used to point to memory. (In this context, the use of one register to address memory is &#147;base addressing,&#148; no matter what register is used.) <B>MOV AX, [BX&#43;DI]</B> and <B>MOV CL, [BP&#43;SI&#43;10]</B> perform indexed addressing; <B>MOV AX,[BX]</B> and <B>MOV DL, [SI&#43;1]</B> do not.</P>
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/12-02i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Therefore, in real mode, the rule is to avoid using two registers to point to memory whenever possible. Often, this simply means adding the two registers together outside a loop before memory is actually addressed.</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>Therefore, in real mode, the rule is to avoid using two registers to point to memory whenever possible. Often, this simply means adding the two registers together outside a loop before memory is actually addressed.</I></SMALL>
</TABLE>
<P>As an example, you might adhere to this rule by replacing the code
</P>