home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / zoa / zen_list.exe / LST11-26.ASM < prev    next >
Assembly Source File  |  1990-02-15  |  3KB  |  103 lines

  1. ;
  2. ; *** Listing 11-26 ***
  3. ;
  4. ; Determines whether two zero-terminated strings differ
  5. ; ignoring case-only differences, and if so where, using
  6. ; LODS.
  7. ;
  8.     jmp    Skip
  9. ;
  10. TestString1    label    byte
  11.     db    'THIS IS A TEST STRING THAT IS '
  12.     db    'Z'
  13.     db    'TERMINATED WITH A ZERO BYTE...',0
  14. TestString2    label    byte
  15.     db    'This is a test string that is '
  16.     db    'a'
  17.     db    'terminated with a zero byte...',0
  18. ;
  19. ; Macro to convert the specified register to uppercase if
  20. ; it is lowercase.
  21. ;
  22. TO_UPPER macro    REGISTER
  23.     local    NotLower
  24.     cmp    REGISTER,ch    ;below 'a'?
  25.     jb    NotLower    ;yes, not lowercase
  26.     cmp    REGISTER,cl    ;above 'z'?
  27.     ja    NotLower    ;yes, not lowercase
  28.     and    REGISTER,bl    ;lowercase-convert to uppercase
  29. NotLower:
  30.     endm
  31. ;
  32. ; Compares two zero-terminated strings, ignoring differences
  33. ; that are only uppercase/lowercase differences.
  34. ;
  35. ; Input:
  36. ;    DS:SI = first zero-terminated string
  37. ;    ES:DI = second zero-terminated string
  38. ;
  39. ; Output:
  40. ;    DS:SI = pointer to first case-insensitive differing
  41. ;        location in first string, or 0 if the byte
  42. ;        wasn't found
  43. ;    ES:DI = pointer to first case-insensitive differing
  44. ;        location in second string, or 0 if the byte
  45. ;        wasn't found
  46. ;
  47. ; Registers altered: AX, BL, CX, DX, SI, DI
  48. ;
  49. ; Direction flag cleared
  50. ;
  51. ; Note: Does not handle strings that are longer than 64K
  52. ;    bytes or cross segment boundaries.
  53. ;
  54. CompareStringsNoCase:
  55.     cld
  56.     mov    cx,'az'    ;for fast register-register
  57.             ; comparison in the loop
  58.     mov    bl,not 20h ;for fast conversion to
  59.             ; uppercase in the loop
  60. CompareStringsLoop:
  61.     lodsw        ;get the next 2 bytes
  62.     mov    dx,es:[di] ; from each string
  63.     inc    di    ;point to the next word in the
  64.     inc    di    ; second string
  65.     TO_UPPER al    ;convert the first byte from each
  66.     TO_UPPER dl    ; string to uppercase
  67.     cmp    al,dl    ;do the first bytes match?
  68.     jnz    CompareStringsDifferent1 ;the strings differ
  69.     and    al,al    ;is the first byte the terminating
  70.             ; zero?
  71.     jz    CompareStringsSame
  72.             ;yes, we're done with a match
  73.     TO_UPPER ah    ;convert the second byte from each
  74.     TO_UPPER dh    ; string to uppercase
  75.     cmp    ah,dh    ;do the second bytes match?
  76.     jnz    CompareStringsDifferent ;the strings differ
  77.     and    ah,ah    ;is the second byte the terminating
  78.             ; zero?
  79.     jnz    CompareStringsLoop
  80.             ;no, do the next 2 bytes
  81. CompareStringsSame:
  82.     sub    si,si    ;return 0 pointers indicating that
  83.     mov    di,si    ; the strings are identical
  84.     ret
  85. CompareStringsDifferent1:
  86.     dec    si    ;point back to the second byte of
  87.     dec    di    ; the word we just compared
  88. CompareStringsDifferent:
  89.     dec    si    ;point back to the first byte of the
  90.     dec    di    ; word we just compared
  91.     ret
  92. ;
  93. Skip:
  94.     call    ZTimerOn
  95.     mov    si,offset TestString1 ;point to one string
  96.     mov    di,seg TestString2
  97.     mov    es,di
  98.     mov    di,offset TestString2 ;point to other string
  99.     call    CompareStringsNoCase    ;and compare the
  100.                     ; strings without
  101.                     ; regard for case
  102.     call    ZTimerOff
  103.