Change bold code snippets to inline code blocks

This commit is contained in:
James Gregory 2013-12-31 17:12:29 +11:00
commit 3c76d884ef
185 changed files with 1772 additions and 1772 deletions

View file

@ -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:
> ![](images/i.jpg)
> 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.)
> ![](images/i.jpg)
> 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!