home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / zendisk2.zip / LST11-16.ASM < prev    next >
Assembly Source File  |  1990-02-15  |  4KB  |  121 lines

  1. ;
  2. ; *** Listing 11-16 ***
  3. ;
  4. ; Finds the last non-blank character in a string, using
  5. ; REPNZ SCASB to find the end of the string and then using
  6. ; REPZ SCASW from the end of the string to find the last
  7. ; non-blank character.
  8. ;
  9.     jmp    Skip
  10. ;
  11. TestString    label    byte
  12.     db    'This is a test string with blanks....'
  13.     db    '                                     ',0
  14. ;
  15. ; Finds the last non-blank character in the specified
  16. ; zero-terminated string.
  17. ;
  18. ; Input:
  19. ;    DS:SI = zero-terminated string to search
  20. ;
  21. ; Output:
  22. ;    SI = pointer to last non-blank character in string,
  23. ;        or 0 if there are no non-blank characters in
  24. ;        the string
  25. ;
  26. ; Registers altered: AX, CX, SI, DI, ES
  27. ;
  28. ; Direction flag cleared
  29. ;
  30. ; Note: Do not pass a string that starts at offset 0 (SI=0),
  31. ;    since a return pointer to the first byte and failure
  32. ;    to find a non-blank character would be
  33. ;    indistinguishable.
  34. ;
  35. ; Note: If there is no terminating zero in the first 64K-1
  36. ;    bytes of the string, it is assumed without checking
  37. ;    that byte #64K-1 (the 1 byte in the segment that
  38. ;    wasn't checked) is the terminating zero.
  39. ;
  40. ; Note: Does not handle strings that are longer than 64K
  41. ;    bytes or cross segment boundaries.
  42. ;
  43. FindLastNonBlankInString:
  44.     push    ds
  45.     pop    es
  46.     mov    di,si    ;SCAS uses ES:DI
  47.     sub    al,al    ;first we'll search for the
  48.             ; terminating zero
  49.     mov    cx,0ffffh ;we'll search the longest possible
  50.             ; string
  51.     cld
  52.     repnz    scasb    ;find the terminating zero
  53.     dec    di    ;point back to the zero
  54.     cmp    [di],al ;make sure this is a zero.
  55.             ; (Remember, ES=DS)
  56.     jnz    FindLastNonBlankInStringSearchBack
  57.             ; not a zero. The string must be
  58.             ; exactly 64K bytes long, so we've
  59.             ; come up 1 byte short of the zero
  60.             ; that we're assuming is at byte
  61.             ; 64K-1. That means we're already
  62.             ; pointing to the byte before the
  63.             ; zero
  64.     dec    di    ;point to the byte before the zero
  65.     inc    cx    ;don't count the terminating zero
  66.             ; as one of the characters we've
  67.             ; searched through (and have to
  68.             ; search back through)
  69. FindLastNonBlankInStringSearchBack:
  70.     std        ;we'll search backward
  71.     not    cx    ;length of string, not including
  72.             ; the terminating zero
  73.     mov    ax,2020h ;now we're looking for a space
  74.     shr    cx,1    ;divide by 2 to get a word count
  75.     jnc    FindLastNonBlankInStringWord
  76.     scasb        ;see if the odd byte is the last
  77.             ; non-blank character
  78.     jnz    FindLastNonBlankInStringFound
  79.             ;it is, so we're done
  80. FindLastNonBlankInStringWord:
  81.     jcxz    FindLastNonBlankInStringNoMatch
  82.             ;if there's nothing left to check,
  83.             ; there are no non-blank characters
  84.     dec    di    ;point back to the start of the
  85.             ; next word, not byte
  86.     repz    scasw    ;find the first non-blank character
  87.     jz    FindLastNonBlankInStringNoMatch
  88.             ;there is no non-blank character in
  89.             ; this string
  90.     inc    di    ;undo 1 byte of SCASW's overrun, so
  91.             ; this looks like SCASB's overrun
  92.     cmp    [di+2],al ;which of the 2 bytes we just
  93.             ; checked was the last non-blank
  94.             ; character?
  95.     jz    FindLastNonBlankInStringFound
  96.     inc    di    ;the byte at the higher address was
  97.             ; the last non-blank character, so
  98.             ; adjust by 1 byte
  99. FindLastNonBlankInStringFound:
  100.     inc    di    ;point to the non-blank character
  101.             ; we just found, correcting for
  102.             ; overrun of SCASB running from high
  103.             ; addresses to low
  104.     mov    si,di    ;return pointer to the last
  105.             ; non-blank in SI
  106.     cld
  107.     ret
  108. FindLastNonBlankInStringNoMatch:
  109.     sub    si,si    ;return that we didn't find a
  110.             ; non-blank character
  111.     cld
  112.     ret
  113. ;
  114. Skip:
  115.     call    ZTimerOn
  116.     mov    si,offset TestString     ;string to search
  117.     call    FindLastNonBlankInString ;search for the
  118.                     ; last non-blank
  119.                     ; character
  120.     call    ZTimerOff
  121.