Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
18
13-03.md
18
13-03.md
|
|
@ -47,13 +47,13 @@ and the only cost is that the previous contents of AX are destroyed.
|
|||
|
||||
Likewise, popping a memory location takes six cycles, but popping a
|
||||
register and writing it to memory takes only two cycles combined. The
|
||||
*i486 Microprocessor Programmer’s Reference Manual* lists a 4-cycle
|
||||
*i486 Microprocessor Programmer's Reference Manual* lists a 4-cycle
|
||||
execution time for popping a register, but pay that no mind; popping a
|
||||
register takes only 1 cycle.
|
||||
|
||||
Why is it that such a convenient operation as pushing or popping memory
|
||||
is so slow? The rule on the 486 is that simple operations, which can be
|
||||
executed in a single cycle by the 486’s RISC core, are fast; whereas
|
||||
executed in a single cycle by the 486's RISC core, are fast; whereas
|
||||
complex operations, which must be carried out in microcode just as they
|
||||
were on the 386, are almost all relatively slow. Slow, complex
|
||||
operations include all the string instructions except **REP MOVS,** as
|
||||
|
|
@ -61,7 +61,7 @@ well as **XLAT, LOOP,** and, of course, **PUSH *mem*** and **POP
|
|||
*mem.***
|
||||
|
||||
------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
 *Whenever possible, try to use the 486’s 1-cycle instructions, including **MOV, ADD, SUB, CMP, ADC, SBB, XOR, AND, OR, TEST, LEA**, and **PUSH reg** and **POP reg**. These instructions have an added benefit in that it’s often possible to rearrange them for maximum pipeline efficiency, as is the case with Terje’s optimization described earlier in this chapter.*
|
||||
 *Whenever possible, try to use the 486's 1-cycle instructions, including **MOV, ADD, SUB, CMP, ADC, SBB, XOR, AND, OR, TEST, LEA**, and **PUSH reg** and **POP reg**. These instructions have an added benefit in that it's often possible to rearrange them for maximum pipeline efficiency, as is the case with Terje's optimization described earlier in this chapter.*
|
||||
------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
### Optimal 1-Bit Shifts and Rotates {#Heading6}
|
||||
|
|
@ -72,9 +72,9 @@ forms—as in **ROR AX,1** and **SHL BX,1—**are *3-cycle* instructions. Go
|
|||
figure.
|
||||
|
||||
Assemblers default to the 1-bit instruction for 1-bit shifts and
|
||||
rotates. That’s not unreasonable since the 1-bit form is a byte shorter
|
||||
rotates. That's not unreasonable since the 1-bit form is a byte shorter
|
||||
and is just as fast as the n-bit forms on a 386 and faster on a 286, and
|
||||
the n-bit form doesn’t even exist on an 8088. In a really critical loop,
|
||||
the n-bit form doesn't even exist on an 8088. In a really critical loop,
|
||||
however, it might be worth hand-assembling the n-bit form of a
|
||||
single-bit shift or rotate in order to save that cycle. The easiest way
|
||||
to do this is to assemble a 2-bit form of the desired instruction, as in
|
||||
|
|
@ -92,14 +92,14 @@ code as follows:
|
|||
|
||||
At the end of this sequence, DX will contain 2, and the fast n-bit
|
||||
version of **SHL AX,1** will have executed. If you use this approach,
|
||||
I’d recommend using a macro, rather than sticking DBs in the middle of
|
||||
I'd recommend using a macro, rather than sticking DBs in the middle of
|
||||
your code.
|
||||
|
||||
Again, this technique is advantageous *only* on a 486. It also doesn’t
|
||||
Again, this technique is advantageous *only* on a 486. It also doesn't
|
||||
apply to **RCL** and **RCR,** where you definitely want to use the 1-bit
|
||||
versions whenever you can, because the n-bit versions are horrendously
|
||||
slow. But if you’re optimizing for the 486, these tidbits can save a few
|
||||
critical cycles—and Lord knows that if you’re optimizing for the
|
||||
slow. But if you're optimizing for the 486, these tidbits can save a few
|
||||
critical cycles—and Lord knows that if you're optimizing for the
|
||||
486—that is, if you need even more performance than you get from
|
||||
unoptimized code on a 486—you almost certainly need all the speed you
|
||||
can get.
|
||||
|
|
|
|||
Loading…
Reference in a new issue