Use backtick code blocks for syntax highlighting

This commit is contained in:
James Gregory 2013-12-31 11:38:48 +11:00
commit f658bfbb40
203 changed files with 26546 additions and 25801 deletions

View file

@ -19,9 +19,11 @@ simple task of setting bit N of AX to 1.
The obvious way to do this is to place N in CL, rotate the bit into
position, and OR it with AX, as follows:
MOV BX,1
SHL BX,CL
OR AX,BX
```nasm
MOV BX,1
SHL BX,CL
OR AX,BX
```
This solution is obvious because it takes good advantage of the special
ability of the x86 family to shift or rotate by the variable number of
@ -31,15 +33,17 @@ bit number in BX, and look the shifted bit up, as shown in Listing 7.3.
**LISTING 7.3 L7-3.ASM**
SHL BX,1 ;prepare for word sized look up
OR AX,ShiftTable[BX] ;look up the bit and OR it in
:
ShiftTable LABEL WORD
BIT_PATTERN=0001H
REPT 16
DW BIT_PATTERN
BIT_PATTERN=BIT_PATTERN SHL 1
ENDM
```nasm
SHL BX,1 ;prepare for word sized look up
OR AX,ShiftTable[BX] ;look up the bit and OR it in
:
ShiftTable LABEL WORD
BIT_PATTERN=0001H
REPT 16
DW BIT_PATTERN
BIT_PATTERN=BIT_PATTERN SHL 1
ENDM
```
Even though it accesses memory, this approach takes only 20 cycles—more
than twice as fast as the variable shift. Once again, we were able to
@ -55,14 +59,16 @@ code snippet in Listing 7.4.
**LISTING 7.4 L7-4.ASM**
OR EAX,ShiftTable[EBX*4] ;look up the bit and OR it in
:
ShiftTable LABEL DWORD
BIT_PATTERN=0001H
REPT 32
DD BIT_PATTERN
BIT_PATTERN=BIT_PATTERN SHL 1
ENDM
```nasm
OR EAX,ShiftTable[EBX*4] ;look up the bit and OR it in
:
ShiftTable LABEL DWORD
BIT_PATTERN=0001H
REPT 32
DD BIT_PATTERN
BIT_PATTERN=BIT_PATTERN SHL 1
ENDM
```
> ![](images/i.jpg)
> Besides illustrating the advantages of local optimization, this example
@ -119,30 +125,34 @@ addition to the next.
**LISTING 7.5 L7-5.ASM**
CLC ;clear the Carry for the initial addition
LOOP_TOP:
MOV AX,[SI];get next source operand word
ADC [DI],AX;add with Carry to dest operand word
INC SI ;point to next source operand word
INC SI
INC DI ;point to next dest operand word
INC DI
LOOP LOOP_TOP
```nasm
CLC ;clear the Carry for the initial addition
LOOP_TOP:
MOV AX,[SI];get next source operand word
ADC [DI],AX;add with Carry to dest operand word
INC SI ;point to next source operand word
INC SI
INC DI ;point to next dest operand word
INC DI
LOOP LOOP_TOP
```
If **ADD** were used, the Carry flag would have to be saved between
additions, with code along the lines shown in Listing 7.6.
**LISTING 7.6 L7-6.ASM**
CLC ;clear the carry for the initial addition
LOOP_TOP:
MOV AX,[SI] ;get next source operand word
ADC [DI],AX ;add with carry to dest operand word
LAHF ;set aside the carry flag
ADD SI,2 ;point to next source operand word
ADD DI,2 ;point to next dest operand word
SAHF ;restore the carry flag
LOOP LOOP_TOP
```nasm
CLC ;clear the carry for the initial addition
LOOP_TOP:
MOV AX,[SI] ;get next source operand word
ADC [DI],AX ;add with carry to dest operand word
LAHF ;set aside the carry flag
ADD SI,2 ;point to next source operand word
ADD DI,2 ;point to next dest operand word
SAHF ;restore the carry flag
LOOP LOOP_TOP
```
It's not that the Listing 7.6 approach is necessarily better or worse;
that depends on the processor and the situation. The Listing 7.6
@ -182,13 +192,17 @@ an 8088 but are relatively slow instructions on the 486 and Pentium.
There are times when it's a clear liability that **INC** doesn't set the
Carry flag. For instance
INC AX
ADC DX,0
```nasm
INC AX
ADC DX,0
```
does *not* increment the 32-bit value in DX:AX. To do that, you'd need
the following:
ADD AX,1
ADC DX,0
```nasm
ADD AX,1
ADC DX,0
```
As always, pay attention!