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
70
12-03.md
70
12-03.md
|
|
@ -41,22 +41,26 @@ pops up only spottily when the stack pointer is involved.
|
|||
|
||||
For example, you'd certainly expect a sequence such as
|
||||
|
||||
:
|
||||
pop ax
|
||||
ret
|
||||
pop ax
|
||||
et
|
||||
:
|
||||
```nasm
|
||||
:
|
||||
pop ax
|
||||
ret
|
||||
pop ax
|
||||
et
|
||||
:
|
||||
```
|
||||
|
||||
to exhibit the addressing pipeline interruption phenomenon (SP is both
|
||||
destination and addressing register for both instructions, according to
|
||||
Intel), but this code runs in six cycles per **POP/RET** pair, matching
|
||||
the official execution times exactly. Likewise, a sequence like
|
||||
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
```nasm
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
```
|
||||
|
||||
runs in one cycle per instruction, just as it should.
|
||||
|
||||
|
|
@ -65,15 +69,19 @@ destination—for example, to deallocate local variables—and then using
|
|||
**PUSH**, **POP**, or **RET**, definitely can interrupt the addressing
|
||||
pipeline. For example
|
||||
|
||||
add sp,10h
|
||||
ret
|
||||
```nasm
|
||||
add sp,10h
|
||||
ret
|
||||
```
|
||||
|
||||
loses two cycles because SP is the explicit destination of one
|
||||
instruction and then the implied addressing register for the next, and
|
||||
the sequence
|
||||
|
||||
add sp,10h
|
||||
pop ax
|
||||
```nasm
|
||||
add sp,10h
|
||||
pop ax
|
||||
```
|
||||
|
||||
loses two cycles for the same reason.
|
||||
|
||||
|
|
@ -101,22 +109,26 @@ during the next instruction.
|
|||
|
||||
So, for example, it would be a bad idea to do this
|
||||
|
||||
mov ah,o
|
||||
:
|
||||
mov cx,[MemVar1]
|
||||
mov al,[MemVar2]
|
||||
add cx,ax
|
||||
```nasm
|
||||
mov ah,o
|
||||
:
|
||||
mov cx,[MemVar1]
|
||||
mov al,[MemVar2]
|
||||
add cx,ax
|
||||
```
|
||||
|
||||
because AL is loaded by one instruction, then AX is used as the source
|
||||
register for the next instruction. A cycle can be saved simply by
|
||||
rearranging the instructions so that the byte register load isn't
|
||||
immediately followed by the word register usage, like so:
|
||||
|
||||
mov ah,o
|
||||
:
|
||||
mov al,[MemVar2]
|
||||
mov cx,[MemVar1]
|
||||
add cx,ax
|
||||
```nasm
|
||||
mov ah,o
|
||||
:
|
||||
mov al,[MemVar2]
|
||||
mov cx,[MemVar1]
|
||||
add cx,ax
|
||||
```
|
||||
|
||||
Strange as it may seem, this rule is neither arbitrary nor nonsensical.
|
||||
Basically, when a byte destination register is part of a word source
|
||||
|
|
@ -135,10 +147,12 @@ works.
|
|||
In case you're curious, there's no such penalty for the typical **XLAT**
|
||||
sequence like
|
||||
|
||||
mov bx,offset MemTable
|
||||
:
|
||||
mov al,[si]
|
||||
xlat
|
||||
```nasm
|
||||
mov bx,offset MemTable
|
||||
:
|
||||
mov al,[si]
|
||||
xlat
|
||||
```
|
||||
|
||||
even though AL must be converted to a word by **XLAT** before it can be
|
||||
added to BX and used to address memory. In fact, none of the penalties
|
||||
|
|
|
|||
Loading…
Reference in a new issue