Use backtick code blocks for syntax highlighting
This commit is contained in:
parent
8ed9dea394
commit
f658bfbb40
203 changed files with 26546 additions and 25801 deletions
60
06-02.md
60
06-02.md
|
|
@ -19,11 +19,13 @@ 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:
|
||||
|
||||
add bx,si
|
||||
LoopTop:
|
||||
mov al,[bx]
|
||||
inc bx
|
||||
loop LoopTop
|
||||
```nasm
|
||||
add bx,si
|
||||
LoopTop:
|
||||
mov al,[bx]
|
||||
inc bx
|
||||
loop LoopTop
|
||||
```
|
||||
|
||||
Here, **MOV AL,[BX]** is two cycles faster than **MOV AL,[BX+SI]**.
|
||||
|
||||
|
|
@ -73,24 +75,32 @@ source operands.
|
|||
Imagine that we want to add BX to DI, add two to the result, and store
|
||||
the result in AX. The obvious solution is this:
|
||||
|
||||
mov ax,bx
|
||||
add ax,di
|
||||
add ax,2
|
||||
```nasm
|
||||
mov ax,bx
|
||||
add ax,di
|
||||
add ax,2
|
||||
```
|
||||
|
||||
(It would be more compact to increment AX twice than to add two to it,
|
||||
and would probably be faster on an 8088, but that's not what we're after
|
||||
at the moment.) An elegant alternative solution is simply:
|
||||
|
||||
lea ax,[bx+di+2]
|
||||
```nasm
|
||||
lea ax,[bx+di+2]
|
||||
```
|
||||
|
||||
Likewise, either of the following would copy SI plus two to DI
|
||||
|
||||
mov di,si
|
||||
add di,2
|
||||
```nasm
|
||||
mov di,si
|
||||
add di,2
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
lea di,[si+2]
|
||||
```nasm
|
||||
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
|
||||
|
|
@ -135,14 +145,18 @@ bits, so we can now add up to two 32-bit registers and a constant, *and*
|
|||
shift (or multiply) one of the registers to some extent—all with a
|
||||
single instruction. For example,
|
||||
|
||||
lea edi,TableBase[ecx+edx*4]
|
||||
```nasm
|
||||
lea edi,TableBase[ecx+edx*4]
|
||||
```
|
||||
|
||||
replaces all this
|
||||
|
||||
mov edi,edx
|
||||
shl edi,2
|
||||
add edi,ecx
|
||||
add edi,offset TableBase
|
||||
```nasm
|
||||
mov edi,edx
|
||||
shl edi,2
|
||||
add edi,ecx
|
||||
add edi,offset TableBase
|
||||
```
|
||||
|
||||
when pointing to an entry in a doubly indexed table.
|
||||
|
||||
|
|
@ -156,15 +170,19 @@ index on the 386, and can be scaled as the index while being used
|
|||
unchanged as the base. That means that you can, for example, multiply
|
||||
EBX by 5 with:
|
||||
|
||||
lea ebx,[ebx+ebx*4]
|
||||
```nasm
|
||||
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
|
||||
two, or three separate instructions along the lines of the following
|
||||
|
||||
mov edx,ebx
|
||||
shl ebx,2
|
||||
add ebx,edx
|
||||
```nasm
|
||||
mov edx,ebx
|
||||
shl ebx,2
|
||||
add ebx,edx
|
||||
```
|
||||
|
||||
and would in either case require the destruction of the contents of
|
||||
another register.
|
||||
|
|
|
|||
Loading…
Reference in a new issue