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

@ -14,7 +14,7 @@ The two approaches are functionally interchangeable but *not* equivalent
from a performance standpoint, and which is better depends on the
particular context. If it's a one-shot memory access, it's best to let
the processor perform the addition; it's generally faster at doing this
than a separate **ADD** instruction would be. If it's a memory access
than a separate `ADD` instruction would be. If it's a memory access
within a loop, however, it's advantageous on the 8088 CPU to perform the
addition outside the loop, if possible, reducing effective address
calculation time inside the loop, as in the following:
@ -27,13 +27,13 @@ LoopTop:
loop LoopTop
```
Here, **MOV AL,[BX]** is two cycles faster than **MOV AL,[BX+SI]**.
Here, `MOV AL,[BX]` is two cycles faster than `MOV AL,[BX+SI]`.
On a 286 or 386, however, the balance shifts. **MOV AL,[BX+SI]** takes
no longer than **MOV AL,[BX]** on these processors because effective
On a 286 or 386, however, the balance shifts. `MOV AL,[BX+SI]` takes
no longer than `MOV AL,[BX]` on these processors because effective
address calculations generally take no extra time at all. (According to
the MASM manual, one extra clock is required if three memory addressing
components, as in **MOV AL,[BX+SI+1]**, are used. I have not been able
components, as in `MOV AL,[BX+SI+1]`, are used. I have not been able
to confirm this from Intel publications, but then I haven't looked all
that hard.) If you're optimizing for the 286 or 386, then, you can take
advantage of the processor's ability to perform arithmetic as part of
@ -59,15 +59,15 @@ instructions, at that.
How?
With **LEA**, the only instruction that performs memory addressing
calculations but doesn't actually address memory. **LEA** accepts a
With `LEA`, the only instruction that performs memory addressing
calculations but doesn't actually address memory. `LEA` accepts a
standard memory addressing operand, but does nothing more than store the
calculated memory offset in the specified register, which may be any
general-purpose register. The operation of **LEA** is illustrated in
general-purpose register. The operation of `LEA` is illustrated in
Figure 6.1, which also shows the operation of register-to-register
**ADD**, for comparis on.
`ADD`, for comparis on.
What does that give us? Two things that **ADD** doesn't provide: the
What does that give us? Two things that `ADD` doesn't provide: the
ability to perform addition with either two or three operands, and the
ability to store the result in *any* register, not just in one of the
source operands.
@ -102,20 +102,20 @@ or:
lea di,[si+2]
```
Mind you, the only components **LEA** can add are BX or BP, SI or DI,
and a constant displacement, so it's not going to replace **ADD** most
of the time. Also, **LEA** is considerably slower than **ADD** on an
8088, although it is just as fast as **ADD** on a 286 or 386 when fewer
than three memory addressing components are used. **LEA** is 1 cycle
slower than **ADD** on a 486 if the sum of two registers is used to
point to memory, but no slower than **ADD** on a Pentium. On both a 486
and Pentium, **LEA** can also be slowed down by addressing interlocks.
Mind you, the only components `LEA` can add are BX or BP, SI or DI,
and a constant displacement, so it's not going to replace `ADD` most
of the time. Also, `LEA` is considerably slower than `ADD` on an
8088, although it is just as fast as `ADD` on a 286 or 386 when fewer
than three memory addressing components are used. `LEA` is 1 cycle
slower than `ADD` on a 486 if the sum of two registers is used to
point to memory, but no slower than `ADD` on a Pentium. On both a 486
and Pentium, `LEA` can also be slowed down by addressing interlocks.
![**Figure 6.1**  *Operation of ADD Reg,Reg vs. LEA Reg,{Addr}.*](images/06-01.jpg)
#### The Wonders of LEA on the 386 {#Heading5}
**LEA** really comes into its own as a "super-ADD" instruction on the
`LEA` really comes into its own as a "super-ADD" instruction on the
386, 486, and Pentium, where it can take advantage of the enhanced
memory addressing modes of those processors. (The 486 and Pentium offer
the same modes as the 386, so I'll refer only to the 386 from now on.)
@ -129,15 +129,15 @@ that's good for.
Well, the obvious advantage is that any two 32-bit registers, or any
32-bit register and any constant, or any two 32-bit registers and any
constant, can be added together, with the result stored in any register.
This makes the 32-bit **LEA** much more generally useful than the
standard 16-bit **LEA** in the role of an **ADD** with an independent
This makes the 32-bit `LEA` much more generally useful than the
standard 16-bit `LEA` in the role of an `ADD` with an independent
destination.
![**Figure 6.2**  *Operation of the 32-bit LEA reg,[Addr].*](images/06-02.jpg)
But what else can **LEA** do on a 386, besides add?
But what else can `LEA` do on a 386, besides add?
It can multiply any register used as an index. **LEA** can multiply only
It can multiply any register used as an index. `LEA` can multiply only
by the power-of-two values 2, 4, or 8, but that's useful more often than
you might imagine, especially when dealing with pointers into tables.
Besides, multiplying by 2, 4, or 8 amounts to a left shift of 1, 2, or 3
@ -162,8 +162,8 @@ when pointing to an entry in a doubly indexed table.
### Multiplication with LEA Using Non-Powers of Two {#Heading6}
Are you impressed yet with all that **LEA** can do on the 386? Believe
it or not, one more feature still awaits us. **LEA** can actually
Are you impressed yet with all that `LEA` can do on the 386? Believe
it or not, one more feature still awaits us. `LEA` can actually
perform a fast multiply of a 32-bit register by some values *other* than
powers of two. You see, the same 32-bit register can be both base and
index on the 386, and can be scaled as the index while being used
@ -174,8 +174,8 @@ EBX by 5 with:
lea ebx,[ebx+ebx*4]
```
Without **LEA** and scaling, multiplication of EBX by 5 would require
either a relatively slow **MUL**, along with a set-up instruction or
Without `LEA` and scaling, multiplication of EBX by 5 would require
either a relatively slow `MUL`, along with a set-up instruction or
two, or three separate instructions along the lines of the following
```nasm
@ -192,11 +192,11 @@ cycles is a pretty neat trick, even though it works only on a 386 or
486.
> ![](images/i.jpg)
> The full list of values that **LEA** can multiply a register by on a 386
> The full list of values that `LEA` can multiply a register by on a 386
> or 486 is: 2, 3, 4, 5, 8, and 9. That list doesn't include every
> multiplier you might want, but it covers some commonly used ones, and
> the performance is hard to beat.
I'd like to extend my thanks to Duane Strong of Metagraphics for his
help in brainstorming uses for the 386 version of **LEA** and for
help in brainstorming uses for the 386 version of `LEA` and for
pointing out the complications of 486 instruction timings.