home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / asm / SET_ASM.ZIP / SETS.ASM next >
Encoding:
Assembly Source File  |  1988-12-30  |  12.8 KB  |  410 lines

  1. page 60,132
  2. title    Sets 1.01
  3. ;--------------------------------------------------------------
  4. ;  Program     : Sets (Set handling package)
  5. ;  Version    : 1.01
  6. ;  System      : IBM PC DOS 2.00+
  7. ;  Language    : IBM 8088/86 Macro Assembler
  8. ;  Author      : (C) 1984 by Tom Swan
  9. ;  Address    : Swan Software  P.O. Box 206  Lititz PA  17543
  10. ;--------------------------------------------------------------
  11. true    equ    -1
  12. false    equ    0
  13. host    equ    false            ;true for host program only
  14. maxfn    equ    10            ;maximum function number
  15. ;--------------------------------------------------------------
  16. ;
  17. ;  * All sets are composed of 32 bytes.  each bit represents
  18. ;    one of 256 values in the set.  If the bit = 1, that value
  19. ;    is in the set, else that value is absent.
  20. ;
  21. ;  * Except for flags, all registers are preserved.
  22. ;
  23. ;  * Set routines are called by placing a selection value in ah and
  24. ;    calling "sets".  See individual routines for exact parameters.
  25. ;
  26. ;    example:  mov  dl,value        ;value to test
  27. ;          lea  di,anyset    ;address first byte in set
  28. ;          mov  ah,0        ;select set membership test
  29. ;          call sets        ;call set routine
  30. ;          jnz  success        ;found value in set
  31. ;
  32. ;  * Procedures in the module include:
  33. ;
  34. ;        (ah) = 0  set membership
  35. ;        (ah) = 1  set union
  36. ;        (ah) = 2  set difference
  37. ;        (ah) = 3  set intersection
  38. ;        (ah) = 4  make set from string
  39. ;        (ah) = 5  make set alternate entry
  40. ;        (ah) = 6  set inclusion
  41. ;        (ah) = 7  set comparison
  42. ;        (ah) = 8  add single element to set
  43. ;        (ah) = 9  copy set to set
  44. ;        (ah) = 10  make null set
  45. ;
  46. ;--------------------------------------------------------------
  47. page
  48. dgroup    group    dseg
  49. cgroup    group    cseg
  50.     assume    cs:cgroup, ds:dgroup, es:dgroup, ss:nothing
  51. ;---------------------------------------
  52. ;    Code Segment
  53. ;---------------------------------------
  54. cseg    segment    byte public 'code'
  55.     include    sets.ext        ;include global equates
  56.     public    sets
  57. sets    proc    near
  58.     cld                ;clear df (set auto-increment mode)
  59.     push    ax            ;save all registers
  60.     push    bx
  61.     push    cx
  62.     push    dx
  63.     push    di
  64.     push    si
  65.  
  66. ; Use function number in ah as an offset into a jumptable containing
  67. ; the addresses of the various set functions.  Jump to selected function.
  68.  
  69.     cmp    ah,maxfn        ;test for illegal selector
  70.     ja    setexit            ;exit if ah > 6
  71.     mov    bx,offset jumptable    ;bx=base addr (in cseg)
  72.     mov    al,ah            ;place function number in al
  73.     xor    ah,ah            ;zero ah to make word in ax
  74.     shl    ax,1            ;ax<-ax*2 (16-bit word offset)
  75.     add    bx,ax            ;bx<-bx+ax forming table address 
  76.     jmp    word ptr cs:[bx]    ;jump to routine at cs:[bx]
  77. ; All routines jump to here when done.  Restore all destroyed
  78. ; registers and return to caller.
  79. setexit:
  80.     pop    si            ;restore all registers
  81.     pop    di
  82.     pop    dx
  83.     pop    cx
  84.     pop    bx
  85.     pop    ax
  86.     ret                ;return to caller
  87. sets    endp
  88. page
  89. ;----------------------------------------------------------
  90. ; SETCALC
  91. ;----------------------------------------------------------
  92. ; Purpose    -- calculate word address and bit position
  93. ;           for a set value.
  94. ;
  95. ; Called by    -- functions 0,4,5,8
  96. ;
  97. ; Arguments    -- (es:di) = address of set (first word)
  98. ;              (dl) = value (8-bits) to test
  99. ;
  100. ; Returns    -- (al) = byte from set for value in dl
  101. ;           (ah) = bit in relative position for value
  102. ;           (bx) = offset of word (i.e. at ds:[di+bx])
  103. ;----------------------------------------------------------
  104. dseg    segment byte public 'data'
  105. bittab    db    01h,02h,04h,08h,10h,20h,40h,80h    ;bits 0..7 set = 1
  106. dseg    ends
  107. setcalc proc    near
  108. ; byte offset = value div 8
  109. ; bit offset = value mod 8
  110.     push    di            ;save di register
  111.     xor    ax,ax            ;zero ax so that ah=0
  112.     mov    al,dl            ;set ax=value dl (16-bits)
  113.     mov    bh,8            ;set bh=divisor
  114.     div    bh            ;al <- ax div bh ;ah <- ax mod bh
  115.     xor    bx,bx            ;zero bx so that bh=0
  116.     mov    bl,ah            ;bx <- value mod 8 (bittab offset)
  117.     lea    di,bittab        ;address 8-byte bit table
  118.     mov    ah,byte ptr [di+bx]    ;ah <- bit in relative position
  119.     pop    di            ;restore register (address of set)
  120.     mov    bl,al            ;bx <- value div 8 (set offset)
  121.     mov    al,byte ptr [di+bx]    ;al <- byte from set for value dl
  122.     ret                ;return to caller
  123. setcalc    endp                ;end procedure
  124. page
  125. ;----------------------------------------------------------
  126. ; SET0    (ah=0)    set membership        (v in set)
  127. ;----------------------------------------------------------
  128. ; Purpose    -- test for presence of value (v) in set
  129. ;
  130. ; Called by    -- set jump table
  131. ;
  132. ; Calls        -- setcalc
  133. ;
  134. ; Arguments    -- (es:di) = address of set
  135. ;              (dl) = 8-bit value (v)
  136. ;
  137. ; Registers    -- zf=1 = value not present    (use jz)
  138. ;           zf=0 = value present        (use jnz)
  139. ;----------------------------------------------------------
  140. set0    proc    near
  141.     call    setcalc            ;ax=value; bx=address; cx=bit
  142.     test    al,ah            ;test bit in ah against set val
  143.     jmp    setexit            ;end function 0
  144. set0    endp
  145. page
  146. ;----------------------------------------------------------
  147. ; SET1    (ah=1)    set union    (set2 <- set1 + set2)
  148. ;----------------------------------------------------------
  149. ; Purpose    -- make set2 equal to all elements in set1
  150. ;           plus elements already in set2.
  151. ;
  152. ; Called by    -- main jump table
  153. ;
  154. ; Calls        -- none
  155. ;
  156. ; Arguments    -- (ds:si) = address of set1
  157. ;                  (es:di) = address of set2
  158. ;
  159. ; Registers    -- none
  160. ;----------------------------------------------------------
  161. set1    proc    near
  162.     mov    cx,setlen        ;cx=number bytes in set
  163. set1_1:
  164.     lodsb                ;al<-[si]; si<-si+1
  165.     or    byte ptr [di],al    ;[di]<-logical or of [di],al
  166.     inc    di            ;advance destination set pointer
  167.     loop    set1_1            ;loop on cx
  168.     jmp    setexit            ;end set1
  169. set1    endp
  170. page
  171. ;----------------------------------------------------------
  172. ; SET2    (ah=2)    set difference        (set2 <- set1 - set2)
  173. ;----------------------------------------------------------
  174. ; Purpose    -- make set2 equal to the set of elements of set1
  175. ;           which are not also members of the original set2
  176. ;
  177. ; Called by    -- main jump table
  178. ;
  179. ; Calls        -- none
  180. ;
  181. ; Arguments    -- (ds:si) = address of set1
  182. ;                  (es:di) = address of set2
  183. ;
  184. ; Registers    -- none
  185. ;----------------------------------------------------------
  186. set2    proc    near
  187.     mov    cx,setlen        ;cx=number bytes in set
  188. set2_1:
  189.     xor    byte ptr [di],0ffh    ;complement byte at [di]
  190.     lodsb                ;al<-[si]; si<-si+1
  191.     and    byte ptr [di],al    ;[di]<- logical and of [di],al
  192.     inc    di            ;advance destination set pointer
  193.     loop    set2_1            ;loop on cx
  194.     jmp    setexit            ;end function 2
  195. set2    endp
  196. page
  197. ;----------------------------------------------------------
  198. ; SET3    (ah=3)    set intersection    (set2 <- set1 * set2)
  199. ;----------------------------------------------------------
  200. ; Purpose    -- make set2 equal to the set of elements in
  201. ;           both set1 and the original set2
  202. ;
  203. ; Called by    -- main jump table
  204. ;
  205. ; Calls        -- none
  206. ;
  207. ; Arguments    -- (ds:si) = address of set1
  208. ;                  (es:di) = address of set2
  209. ;
  210. ; Registers    -- none
  211. ;----------------------------------------------------------
  212. set3    proc    near
  213.     mov    cx,setlen        ;cx=number bytes in set
  214. set3_1:
  215.     lodsb                ;al<-[si]; si:=si+1
  216.     and    byte ptr [di],al    ;[di]<- logical and of [di],al
  217.     inc    di            ;advance destination set pointer
  218.     loop    set3_1            ;loop on cx
  219.     jmp    setexit            ;end set3
  220. set3    endp
  221. page
  222. ;----------------------------------------------------------
  223. ; SET4    (ah=4)    make set from string    set <- [s(1),s(2),...,s(n)]
  224. ;----------------------------------------------------------
  225. ; Purpose    -- insert 8-bit elements from string (s)
  226. ;           into the set.  Assumes first byte of string
  227. ;           indicates length.
  228. ;
  229. ; Called by    -- main jump table
  230. ;
  231. ; Calls        -- set5        (via fall-through)
  232. ;
  233. ; Arguments    -- (ds:si) = address first byte of string (s[0])
  234. ;                  (es:di) = address of destination set
  235. ;
  236. ; Registers    -- none
  237. ;----------------------------------------------------------
  238. set4    proc    near
  239.     mov    cx,setlen        ;set cx=number bytes in set
  240.     xor     al,al            ;set al=0 (value to store in set)
  241.     push    di            ;save di (set address) on stack
  242.  
  243. ;----- make existing set null
  244.  
  245. rep    stosb                ;store al at [di] until cx=0
  246.     pop    di            ;restore di
  247.                     ;fall through to set5 procedure
  248. set4    endp
  249. page
  250. ;----------------------------------------------------------
  251. ; SET5    (ah=5)    make set alternate    set <- set + [s(1),s(2),...,s(n)]
  252. ;----------------------------------------------------------
  253. ; Purpose    -- add 8-bit elements from string s into
  254. ;           an existing set
  255. ;
  256. ; Called by    -- main jump table
  257. ;           set4            (via fall-through)
  258. ;
  259. ; Calls        -- setcalc
  260. ;
  261. ; Arguments    -- (ds:si) = address first byte of string (s[0])
  262. ;                  (es:di) = address of destination set
  263. ;
  264. ; Registers    -- none
  265. ;----------------------------------------------------------
  266. set5    proc    near
  267.     xor    cx,cx            ;zero cx so that ch=0
  268.     lodsb                ;get length al<-[si]; si<-si+1
  269.     mov    cl,al            ;set cx=count of chars in string
  270.     jcxz    set5_2            ;exit on null string
  271. set5_1:
  272.     lodsb                ;get byte al<-[si]; si<-si+1
  273.     mov    dl,al            ;move value in al to dl for setcalc
  274.     call    setcalc            ;calculate byte offset bx; bit ah
  275.     or    byte ptr [di+bx],ah    ;or bit in ah into set byte
  276.     loop    set5_1            ;cx<-cx-1; if cx<>0 then loop
  277. set5_2:
  278.     jmp    setexit            ;end set5
  279. set5    endp
  280. page
  281. ;----------------------------------------------------------
  282. ; SET6    (ah=6)    set inclusion          set1 <= set2
  283. ;----------------------------------------------------------
  284. ; Purpose    -- test if set1 is a subset of set2
  285. ;
  286. ; Called by    -- main jump table
  287. ;
  288. ; Calls        -- none
  289. ;
  290. ; Arguments    -- (es:di) = address of set1
  291. ;           (ds:si) = address of set2
  292. ;
  293. ; Registers    -- zf = 1 if set1 <= set2    (use je)
  294. ;           zf = 0 if not (set1 <= set2)    (use jne)
  295. ;----------------------------------------------------------
  296. set6    proc    near
  297.     mov    cx,setlen        ;cx=number bytes in set
  298. set6_1:
  299.     lodsb                ;al <- [si]; si := si + 1
  300.     and    al,byte ptr [di]    ;al <- [si] & [di]
  301.     cmp    al,byte ptr [di]    ;compare with original byte
  302.     jne    set6_2            ;jump on difference found
  303.     stosb                ;advances di (value [di] unchanged) 
  304.     loop    set6_1            ;loop on cx (flags preserved)
  305. set6_2:
  306.     jmp    setexit            ;end set6
  307. set6    endp
  308. page
  309. ;----------------------------------------------------------
  310. ; SET7    (ah=7)    set comparison          set1 = set2
  311. ;----------------------------------------------------------
  312. ; Purpose    -- test if set1 equals set2
  313. ;
  314. ; Called by    -- main jump table
  315. ;
  316. ; Calls        -- none
  317. ;
  318. ; Arguments    -- (ds:si) = address of set1
  319. ;           (es:di) = address of set2
  320. ;
  321. ; Registers    -- zf = 1 if set1 = set2    (use je)
  322. ;           zf = 0 if set1 <> set2    (use jne)
  323. ;----------------------------------------------------------
  324. set7    proc    near
  325.     mov    cx,setlen        ;cx=number bytes in set
  326. repz    cmpsb                ;compare [si],[di]
  327.                                         ;loop on cx if equal
  328.     jmp    setexit            ;end set7
  329. set7    endp
  330. page
  331. ;----------------------------------------------------------
  332. ;  SET8    (ah=8)    add element     set1 := set1 + [element]
  333. ;----------------------------------------------------------
  334. ; Purpose    -- add one element to members of a set
  335. ;
  336. ; Called by    -- main jump table
  337. ;
  338. ; Calls        -- setcalc
  339. ;
  340. ; Arguments    -- (es:di) = address of destination set
  341. ;              (dl) = 8-bit element to add
  342. ; Registers    -- none
  343. ;----------------------------------------------------------
  344. set8    proc    near
  345.     call    setcalc            ;calculate byte offset bx; bit ah
  346.     or    byte ptr [di+bx],ah    ;or bit in ah into set byte
  347.     jmp    setexit            ;end set8
  348. set8    endp
  349. page
  350. ;----------------------------------------------------------
  351. ; SET9    (ah=9)    copy set    set1 := set2
  352. ;----------------------------------------------------------
  353. ; Purpose    -- copy one set variable to another
  354. ;
  355. ; Called by    -- main jump table
  356. ;
  357. ; Calls        -- none
  358. ;
  359. ; Arguments    -- (ds:si) = address of set2 (source)
  360. ;                  (es:di) = address of set1 (destination)
  361. ;
  362. ; Registers    -- none
  363. ;----------------------------------------------------------
  364. set9    proc    near
  365.     mov    cx,setlen        ;cx=number bytes in set
  366. rep    movsb                ;copy [di]<-[si] until cx=0
  367.     jmp    setexit            ;end set9
  368. set9    endp
  369. page
  370. ;----------------------------------------------------------
  371. ;  SET10    (ah=10)    make null set        set1 := []
  372. ;----------------------------------------------------------
  373. ; Purpose    -- make a set variable equal to the null set
  374. ;
  375. ; Called by    -- main jump table
  376. ;
  377. ; Calls        -- none
  378. ;
  379. ; Arguments    -- (es:di) = address of set1
  380. ;
  381. ; Registers    -- none
  382. ;----------------------------------------------------------
  383. set10    proc    near
  384.     mov    cx,setlen        ;cx=number bytes in set
  385.     xor    al,al            ;al <- 0
  386. rep    stosb                ;store al at [di] until cx=0
  387.     jmp    setexit            ;end set10
  388. set10    endp
  389. page
  390. ;---------------------------------------
  391. ;    Jump Table (in code segment)
  392. ;---------------------------------------
  393. ; following are the addresses of the individual routines in the set
  394. ; package.  the list of addresses forms a table for selecting a
  395. ; function based on the value in ah.
  396. jumptable:
  397.     dw    set0            ;fn0-set membership
  398.     dw    set1            ;fn1-set union
  399.     dw    set2            ;fn2-set difference
  400.     dw    set3            ;fn3-set intersection
  401.     dw    set4            ;fn4-make set
  402.     dw    set5            ;fn5-add to set
  403.     dw    set6            ;fn6-set inclusion
  404.     dw    set7            ;fn7-set comparison
  405.     dw    set8            ;fn8-add single element
  406.     dw    set9            ;fn9-copy set to set
  407.     dw    set10            ;fn10-make null set
  408. cseg    ends                ;end of code segment
  409.     end                ;end of text
  410.