home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
ddjmag
/
ddj9003.arc
/
PATERSON.LST
< prev
next >
Wrap
File List
|
1990-02-13
|
4KB
|
224 lines
ASSEMBLY LANGUAGE TRICKS OF THE TRADE
by Tim Paterson
#1 Binary-to-ASCII Conversion
add al,"0" ;Handle 0 - 9
cmp al,"9" ;Did it work?
jbe HaveAscii
add al,"A" - ("9" + 1) ;Apply correction for 0AH - 0FH
HaveAscii:
-------------
add al,90H ;90H - 9FH
daa ;90H - 99H, 00H - 05H +CY
adc al,40H ;0D0H - 0D9H +CY, 41H - 46H
daa ;30H - 39H, 41H - 46H = "0"-"9", "A"-"F"
#2 Absolute Value
or ax,ax ;Set flags
jns AxPositive ;Already the right answer if positive
neg ax ;It was negative, so flip sign
AxPositive:
-------------
cwd ;Extend sign through dx
xor ax,dx ;Complement ax if negative
sub ax,dx ;Increment ax if it was negative
#3 Smaller of Two Values (``MIN'')
cmp ax,bx
jl AxSmaller
xchg ax,bx ;Swap smaller into ax
AxSmaller:
-------------
sub ax,bx ;Could overflow if signs are different!!
cwd ;dx = 0 if ax >= bx, dx = 0FFFFH if ax < bx
and ax,dx ;ax = 0 if ax >= bx, ax = ax - bx if ax < bx
add ax,bx ;ax = bx if ax >=bx, ax = ax if ax < bx
#4 Convert to Uppercase
cmp al,"a"
jb CaseOk
cmp al,"z"
ja CaseOk
sub al,"a"-"A" ;In range "a" - "z", apply correction
CaseOk:
-------------
sub al,"a" ;Lower case now 0 - 25
cmp al,"z" - "a" +1 ;Set CY flag if lower case
sbb ah,ah ;ah = 0FFH if lower case, else 0
and ah,"a" - "A" ;ah = correction or zero
sub al,ah ;Apply correction, lower to upper
add al,"a" ;Restore base
#5 Fast String Move
shr cx,1 ;Convert to word count
rep movsw ;Move words
jnc AllMoved ;CY clear if no odd byte
movsb ;Copy that last odd byte
AllMoved:
-------------
shr cx,1 ;Convert to word count
rep movsw ;Move words
adc cx,cx ;Move carry back into cx
rep movsb ;Move one more if odd count
#6 Binary/Decimal Conversion
aam ;al = ones, ah = tens & hundreds
mov cl,al ;Save ones in cl
mov al,ah ;Set up to do it again
aam ;ah = hundreds, al = tens, cl = ones
-------------
;ah = hundreds, al = tens, cl = ones
aad ;Combine hundreds and tens
mov ah,al
mov al,cl ;Move ones to al
aad ;Binary result in ax, mod 256
#7 Multiple Bit Testing
mov al,[Flag]
test al,Bit1
jnz Bit1Set
test al,Bit2
jz BothZero
Bit2Only:
...
Bit1Set:
test al,Bit2
jnz BothOne
Bit1Only:
-------------
test [Flag],Bit1 + Bit2
jz BothZero
jpe BothOne ;Bits are equal, but not both zero
;One (and only one) bit is set
.erre Bit1 EQ 80H ;Verify Bit1 is the sign bit
js Bit1Only
Bit2Only:
#8 Function Dispatcher
;Function number in cx
jcxz Function0
dec cx
jz Function1
dec cx
jz Function2
...
-------------
;Function number in bx
shl bx,1
jmp tDispatch[bx]
-------------
;Function number in cx
jcxz Function0
loop NotFunc1
Function1:
...
NotFunc1:
loop NotFunc2
Function2:
...
NotFunc2:
loop NotFunc3
Function3:
...
#9 Skipping Instructions
Entry1:
mov al,0
jmp Body
Entry2:
mov al,1
jmp Body
Entry3:
mov al,-1
Body:
-------------
SKIP2F MACRO
db 3DH ;Opcode byte for CMP AX,<immed>
ENDM
Entry1:
mov al,0
SKIP2F ;Next 2 bytes are immediate data
Entry2:
mov al,1
SKIP2F ;Next 2 bytes are immediate data
Entry3:
mov al,-1
Body:
The effect of this when entered at Entry1 is:
Entry1:
mov al,0
cmp ax,01B0H ;Data is MOV AL,1
cmp ax,0FFB0H ;Data is MOV AL,-1
Body:
-------------
SKIP2 MACRO ModReg
IFIDNI <ModReg>,<f> ;Modify flags?
db 3DH ;Opcode byte for CMP AX,<immed>
ELSE
?_i = 0
IRP Reg,<ax,cx,dx,bx,sp,bp,si,di>
IFIDNI <ModReg>,<Reg> ;Find the register in list yet?
db 0B8H + ?_i
EXITM
ELSE
?_i = ?_i + 1
ENDIF ;IF ModReg = Reg
ENDM ;IRP
.errnz ?_i EQ 8 ;Flag an error if no match
ENDIF ;IF ModReg = F
ENDM ;SKIP2
;Examples
SKIP2 f ;Modify flags only
SKIP2 ax ;Destroy ax, flags preserved