home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- title Sets 1.01
- ;--------------------------------------------------------------
- ; Program : Sets (Set handling package)
- ; Version : 1.01
- ; System : IBM PC DOS 2.00+
- ; Language : IBM 8088/86 Macro Assembler
- ; Author : (C) 1984 by Tom Swan
- ; Address : Swan Software P.O. Box 206 Lititz PA 17543
- ;--------------------------------------------------------------
- true equ -1
- false equ 0
- host equ false ;true for host program only
- maxfn equ 10 ;maximum function number
- ;--------------------------------------------------------------
- ;
- ; * All sets are composed of 32 bytes. each bit represents
- ; one of 256 values in the set. If the bit = 1, that value
- ; is in the set, else that value is absent.
- ;
- ; * Except for flags, all registers are preserved.
- ;
- ; * Set routines are called by placing a selection value in ah and
- ; calling "sets". See individual routines for exact parameters.
- ;
- ; example: mov dl,value ;value to test
- ; lea di,anyset ;address first byte in set
- ; mov ah,0 ;select set membership test
- ; call sets ;call set routine
- ; jnz success ;found value in set
- ;
- ; * Procedures in the module include:
- ;
- ; (ah) = 0 set membership
- ; (ah) = 1 set union
- ; (ah) = 2 set difference
- ; (ah) = 3 set intersection
- ; (ah) = 4 make set from string
- ; (ah) = 5 make set alternate entry
- ; (ah) = 6 set inclusion
- ; (ah) = 7 set comparison
- ; (ah) = 8 add single element to set
- ; (ah) = 9 copy set to set
- ; (ah) = 10 make null set
- ;
- ;--------------------------------------------------------------
- page
- dgroup group dseg
- cgroup group cseg
- assume cs:cgroup, ds:dgroup, es:dgroup, ss:nothing
- ;---------------------------------------
- ; Code Segment
- ;---------------------------------------
- cseg segment byte public 'code'
- include sets.ext ;include global equates
- public sets
- sets proc near
- cld ;clear df (set auto-increment mode)
- push ax ;save all registers
- push bx
- push cx
- push dx
- push di
- push si
-
- ; Use function number in ah as an offset into a jumptable containing
- ; the addresses of the various set functions. Jump to selected function.
-
- cmp ah,maxfn ;test for illegal selector
- ja setexit ;exit if ah > 6
- mov bx,offset jumptable ;bx=base addr (in cseg)
- mov al,ah ;place function number in al
- xor ah,ah ;zero ah to make word in ax
- shl ax,1 ;ax<-ax*2 (16-bit word offset)
- add bx,ax ;bx<-bx+ax forming table address
- jmp word ptr cs:[bx] ;jump to routine at cs:[bx]
- ; All routines jump to here when done. Restore all destroyed
- ; registers and return to caller.
- setexit:
- pop si ;restore all registers
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret ;return to caller
- sets endp
- page
- ;----------------------------------------------------------
- ; SETCALC
- ;----------------------------------------------------------
- ; Purpose -- calculate word address and bit position
- ; for a set value.
- ;
- ; Called by -- functions 0,4,5,8
- ;
- ; Arguments -- (es:di) = address of set (first word)
- ; (dl) = value (8-bits) to test
- ;
- ; Returns -- (al) = byte from set for value in dl
- ; (ah) = bit in relative position for value
- ; (bx) = offset of word (i.e. at ds:[di+bx])
- ;----------------------------------------------------------
- dseg segment byte public 'data'
- bittab db 01h,02h,04h,08h,10h,20h,40h,80h ;bits 0..7 set = 1
- dseg ends
- setcalc proc near
- ; byte offset = value div 8
- ; bit offset = value mod 8
- push di ;save di register
- xor ax,ax ;zero ax so that ah=0
- mov al,dl ;set ax=value dl (16-bits)
- mov bh,8 ;set bh=divisor
- div bh ;al <- ax div bh ;ah <- ax mod bh
- xor bx,bx ;zero bx so that bh=0
- mov bl,ah ;bx <- value mod 8 (bittab offset)
- lea di,bittab ;address 8-byte bit table
- mov ah,byte ptr [di+bx] ;ah <- bit in relative position
- pop di ;restore register (address of set)
- mov bl,al ;bx <- value div 8 (set offset)
- mov al,byte ptr [di+bx] ;al <- byte from set for value dl
- ret ;return to caller
- setcalc endp ;end procedure
- page
- ;----------------------------------------------------------
- ; SET0 (ah=0) set membership (v in set)
- ;----------------------------------------------------------
- ; Purpose -- test for presence of value (v) in set
- ;
- ; Called by -- set jump table
- ;
- ; Calls -- setcalc
- ;
- ; Arguments -- (es:di) = address of set
- ; (dl) = 8-bit value (v)
- ;
- ; Registers -- zf=1 = value not present (use jz)
- ; zf=0 = value present (use jnz)
- ;----------------------------------------------------------
- set0 proc near
- call setcalc ;ax=value; bx=address; cx=bit
- test al,ah ;test bit in ah against set val
- jmp setexit ;end function 0
- set0 endp
- page
- ;----------------------------------------------------------
- ; SET1 (ah=1) set union (set2 <- set1 + set2)
- ;----------------------------------------------------------
- ; Purpose -- make set2 equal to all elements in set1
- ; plus elements already in set2.
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (ds:si) = address of set1
- ; (es:di) = address of set2
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set1 proc near
- mov cx,setlen ;cx=number bytes in set
- set1_1:
- lodsb ;al<-[si]; si<-si+1
- or byte ptr [di],al ;[di]<-logical or of [di],al
- inc di ;advance destination set pointer
- loop set1_1 ;loop on cx
- jmp setexit ;end set1
- set1 endp
- page
- ;----------------------------------------------------------
- ; SET2 (ah=2) set difference (set2 <- set1 - set2)
- ;----------------------------------------------------------
- ; Purpose -- make set2 equal to the set of elements of set1
- ; which are not also members of the original set2
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (ds:si) = address of set1
- ; (es:di) = address of set2
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set2 proc near
- mov cx,setlen ;cx=number bytes in set
- set2_1:
- xor byte ptr [di],0ffh ;complement byte at [di]
- lodsb ;al<-[si]; si<-si+1
- and byte ptr [di],al ;[di]<- logical and of [di],al
- inc di ;advance destination set pointer
- loop set2_1 ;loop on cx
- jmp setexit ;end function 2
- set2 endp
- page
- ;----------------------------------------------------------
- ; SET3 (ah=3) set intersection (set2 <- set1 * set2)
- ;----------------------------------------------------------
- ; Purpose -- make set2 equal to the set of elements in
- ; both set1 and the original set2
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (ds:si) = address of set1
- ; (es:di) = address of set2
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set3 proc near
- mov cx,setlen ;cx=number bytes in set
- set3_1:
- lodsb ;al<-[si]; si:=si+1
- and byte ptr [di],al ;[di]<- logical and of [di],al
- inc di ;advance destination set pointer
- loop set3_1 ;loop on cx
- jmp setexit ;end set3
- set3 endp
- page
- ;----------------------------------------------------------
- ; SET4 (ah=4) make set from string set <- [s(1),s(2),...,s(n)]
- ;----------------------------------------------------------
- ; Purpose -- insert 8-bit elements from string (s)
- ; into the set. Assumes first byte of string
- ; indicates length.
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- set5 (via fall-through)
- ;
- ; Arguments -- (ds:si) = address first byte of string (s[0])
- ; (es:di) = address of destination set
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set4 proc near
- mov cx,setlen ;set cx=number bytes in set
- xor al,al ;set al=0 (value to store in set)
- push di ;save di (set address) on stack
-
- ;----- make existing set null
-
- rep stosb ;store al at [di] until cx=0
- pop di ;restore di
- ;fall through to set5 procedure
- set4 endp
- page
- ;----------------------------------------------------------
- ; SET5 (ah=5) make set alternate set <- set + [s(1),s(2),...,s(n)]
- ;----------------------------------------------------------
- ; Purpose -- add 8-bit elements from string s into
- ; an existing set
- ;
- ; Called by -- main jump table
- ; set4 (via fall-through)
- ;
- ; Calls -- setcalc
- ;
- ; Arguments -- (ds:si) = address first byte of string (s[0])
- ; (es:di) = address of destination set
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set5 proc near
- xor cx,cx ;zero cx so that ch=0
- lodsb ;get length al<-[si]; si<-si+1
- mov cl,al ;set cx=count of chars in string
- jcxz set5_2 ;exit on null string
- set5_1:
- lodsb ;get byte al<-[si]; si<-si+1
- mov dl,al ;move value in al to dl for setcalc
- call setcalc ;calculate byte offset bx; bit ah
- or byte ptr [di+bx],ah ;or bit in ah into set byte
- loop set5_1 ;cx<-cx-1; if cx<>0 then loop
- set5_2:
- jmp setexit ;end set5
- set5 endp
- page
- ;----------------------------------------------------------
- ; SET6 (ah=6) set inclusion set1 <= set2
- ;----------------------------------------------------------
- ; Purpose -- test if set1 is a subset of set2
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (es:di) = address of set1
- ; (ds:si) = address of set2
- ;
- ; Registers -- zf = 1 if set1 <= set2 (use je)
- ; zf = 0 if not (set1 <= set2) (use jne)
- ;----------------------------------------------------------
- set6 proc near
- mov cx,setlen ;cx=number bytes in set
- set6_1:
- lodsb ;al <- [si]; si := si + 1
- and al,byte ptr [di] ;al <- [si] & [di]
- cmp al,byte ptr [di] ;compare with original byte
- jne set6_2 ;jump on difference found
- stosb ;advances di (value [di] unchanged)
- loop set6_1 ;loop on cx (flags preserved)
- set6_2:
- jmp setexit ;end set6
- set6 endp
- page
- ;----------------------------------------------------------
- ; SET7 (ah=7) set comparison set1 = set2
- ;----------------------------------------------------------
- ; Purpose -- test if set1 equals set2
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (ds:si) = address of set1
- ; (es:di) = address of set2
- ;
- ; Registers -- zf = 1 if set1 = set2 (use je)
- ; zf = 0 if set1 <> set2 (use jne)
- ;----------------------------------------------------------
- set7 proc near
- mov cx,setlen ;cx=number bytes in set
- repz cmpsb ;compare [si],[di]
- ;loop on cx if equal
- jmp setexit ;end set7
- set7 endp
- page
- ;----------------------------------------------------------
- ; SET8 (ah=8) add element set1 := set1 + [element]
- ;----------------------------------------------------------
- ; Purpose -- add one element to members of a set
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- setcalc
- ;
- ; Arguments -- (es:di) = address of destination set
- ; (dl) = 8-bit element to add
- ; Registers -- none
- ;----------------------------------------------------------
- set8 proc near
- call setcalc ;calculate byte offset bx; bit ah
- or byte ptr [di+bx],ah ;or bit in ah into set byte
- jmp setexit ;end set8
- set8 endp
- page
- ;----------------------------------------------------------
- ; SET9 (ah=9) copy set set1 := set2
- ;----------------------------------------------------------
- ; Purpose -- copy one set variable to another
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (ds:si) = address of set2 (source)
- ; (es:di) = address of set1 (destination)
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set9 proc near
- mov cx,setlen ;cx=number bytes in set
- rep movsb ;copy [di]<-[si] until cx=0
- jmp setexit ;end set9
- set9 endp
- page
- ;----------------------------------------------------------
- ; SET10 (ah=10) make null set set1 := []
- ;----------------------------------------------------------
- ; Purpose -- make a set variable equal to the null set
- ;
- ; Called by -- main jump table
- ;
- ; Calls -- none
- ;
- ; Arguments -- (es:di) = address of set1
- ;
- ; Registers -- none
- ;----------------------------------------------------------
- set10 proc near
- mov cx,setlen ;cx=number bytes in set
- xor al,al ;al <- 0
- rep stosb ;store al at [di] until cx=0
- jmp setexit ;end set10
- set10 endp
- page
- ;---------------------------------------
- ; Jump Table (in code segment)
- ;---------------------------------------
- ; following are the addresses of the individual routines in the set
- ; package. the list of addresses forms a table for selecting a
- ; function based on the value in ah.
- jumptable:
- dw set0 ;fn0-set membership
- dw set1 ;fn1-set union
- dw set2 ;fn2-set difference
- dw set3 ;fn3-set intersection
- dw set4 ;fn4-make set
- dw set5 ;fn5-add to set
- dw set6 ;fn6-set inclusion
- dw set7 ;fn7-set comparison
- dw set8 ;fn8-add single element
- dw set9 ;fn9-copy set to set
- dw set10 ;fn10-make null set
- cseg ends ;end of code segment
- end ;end of text