Change bold code snippets to inline code blocks
This commit is contained in:
parent
f658bfbb40
commit
3c76d884ef
185 changed files with 1772 additions and 1772 deletions
34
07-01.md
34
07-01.md
|
|
@ -91,37 +91,37 @@ there? Let me put it this way: If I were, I'd never admit it!
|
|||
#### When LOOP Is a Bad Idea {#Heading3}
|
||||
|
||||
Let's examine first an instruction that is less than it appears to be:
|
||||
**LOOP**. There's no mystery about what **LOOP** does; it decrements CX
|
||||
`LOOP`. There's no mystery about what `LOOP` does; it decrements CX
|
||||
and branches if CX doesn't decrement to zero. It's so beautifully suited
|
||||
to the task of counting down loops that any experienced x86 programmer
|
||||
instinctively stuffs the loop count in CX and reaches for **LOOP** when
|
||||
setting up a loop. That's fine—**LOOP** does, of course, work as
|
||||
instinctively stuffs the loop count in CX and reaches for `LOOP` when
|
||||
setting up a loop. That's fine—`LOOP` does, of course, work as
|
||||
advertised—but there is one problem:
|
||||
|
||||
> 
|
||||
> On half of the processors in the x86 family, **LOOP** is slower than
|
||||
> **DEC CX** followed by **JNZ**. (Granted, **DEC CX/JNZ** isn't precisely
|
||||
> equivalent to **LOOP,** because **DEC** alters the flags and LOOP
|
||||
> On half of the processors in the x86 family, `LOOP` is slower than
|
||||
> `DEC CX` followed by `JNZ`. (Granted, `DEC CX/JNZ` isn't precisely
|
||||
> equivalent to `LOOP`, because `DEC` alters the flags and LOOP
|
||||
> doesn't, but in most situations they're comparable.)
|
||||
|
||||
How can this be? Don't ask me, ask Intel. On the 8088 and 80286,
|
||||
**LOOP** is indeed faster than **DEC CX/JNZ** by a cycle, and **LOOP**
|
||||
`LOOP` is indeed faster than `DEC CX/JNZ` by a cycle, and `LOOP`
|
||||
is generally a little faster still because it's a byte shorter and so
|
||||
can be fetched faster. On the 386, however, things change; **LOOP** is
|
||||
two cycles *slower* than **DEC/JNZ,** and the fetch time for one extra
|
||||
can be fetched faster. On the 386, however, things change; `LOOP` is
|
||||
two cycles *slower* than `DEC/JNZ` and the fetch time for one extra
|
||||
byte on even an uncached 386 generally isn't significant. (Remember that
|
||||
the 386 fetches four instruction bytes at a pop.) **LOOP** is three
|
||||
cycles slower than **DEC/JNZ** on the 486, and the 486 executes
|
||||
the 386 fetches four instruction bytes at a pop.) `LOOP` is three
|
||||
cycles slower than `DEC/JNZ` on the 486, and the 486 executes
|
||||
instructions in so few cycles that those three cycles mean that
|
||||
**DEC/JNZ** is nearly *twice* as fast as **LOOP**. Then, too, unlike
|
||||
**LOOP, DEC** doesn't require that **CX** be used, so the **DEC/JNZ**
|
||||
`DEC/JNZ` is nearly *twice* as fast as `LOOP`. Then, too, unlike
|
||||
`LOOP, DEC` doesn't require that `CX` be used, so the `DEC/JNZ`
|
||||
solution is both faster and more flexible on the 386 and 486, and on the
|
||||
Pentium as well. (By the way, all this is not just theory; I've timed
|
||||
the relative performances of **LOOP** and **DEC CX/JNZ** on a cached
|
||||
the relative performances of `LOOP` and `DEC CX/JNZ` on a cached
|
||||
386, and LOOP really is slower.)
|
||||
|
||||
> 
|
||||
> Things are stranger still for **LOOP**'s relative **JCXZ,** which
|
||||
> branches if and only if CX is zero. **JCXZ** is faster than **AND
|
||||
> CX,CX/JZ** on the 8088 and 80286, and equivalent on the 80386—but is
|
||||
> Things are stranger still for `LOOP`'s relative `JCXZ`, which
|
||||
> branches if and only if CX is zero. `JCXZ` is faster than `AND
|
||||
> CX,CX/JZ` on the 8088 and 80286, and equivalent on the 80386—but is
|
||||
> about twice as slow on the 486!
|
||||
Loading…
Reference in a new issue