home *** CD-ROM | disk | FTP | other *** search
- ;
- ; *** Listing 11-16 ***
- ;
- ; Finds the last non-blank character in a string, using
- ; REPNZ SCASB to find the end of the string and then using
- ; REPZ SCASW from the end of the string to find the last
- ; non-blank character.
- ;
- jmp Skip
- ;
- TestString label byte
- db 'This is a test string with blanks....'
- db ' ',0
- ;
- ; Finds the last non-blank character in the specified
- ; zero-terminated string.
- ;
- ; Input:
- ; DS:SI = zero-terminated string to search
- ;
- ; Output:
- ; SI = pointer to last non-blank character in string,
- ; or 0 if there are no non-blank characters in
- ; the string
- ;
- ; Registers altered: AX, CX, SI, DI, ES
- ;
- ; Direction flag cleared
- ;
- ; Note: Do not pass a string that starts at offset 0 (SI=0),
- ; since a return pointer to the first byte and failure
- ; to find a non-blank character would be
- ; indistinguishable.
- ;
- ; Note: If there is no terminating zero in the first 64K-1
- ; bytes of the string, it is assumed without checking
- ; that byte #64K-1 (the 1 byte in the segment that
- ; wasn't checked) is the terminating zero.
- ;
- ; Note: Does not handle strings that are longer than 64K
- ; bytes or cross segment boundaries.
- ;
- FindLastNonBlankInString:
- push ds
- pop es
- mov di,si ;SCAS uses ES:DI
- sub al,al ;first we'll search for the
- ; terminating zero
- mov cx,0ffffh ;we'll search the longest possible
- ; string
- cld
- repnz scasb ;find the terminating zero
- dec di ;point back to the zero
- cmp [di],al ;make sure this is a zero.
- ; (Remember, ES=DS)
- jnz FindLastNonBlankInStringSearchBack
- ; not a zero. The string must be
- ; exactly 64K bytes long, so we've
- ; come up 1 byte short of the zero
- ; that we're assuming is at byte
- ; 64K-1. That means we're already
- ; pointing to the byte before the
- ; zero
- dec di ;point to the byte before the zero
- inc cx ;don't count the terminating zero
- ; as one of the characters we've
- ; searched through (and have to
- ; search back through)
- FindLastNonBlankInStringSearchBack:
- std ;we'll search backward
- not cx ;length of string, not including
- ; the terminating zero
- mov ax,2020h ;now we're looking for a space
- shr cx,1 ;divide by 2 to get a word count
- jnc FindLastNonBlankInStringWord
- scasb ;see if the odd byte is the last
- ; non-blank character
- jnz FindLastNonBlankInStringFound
- ;it is, so we're done
- FindLastNonBlankInStringWord:
- jcxz FindLastNonBlankInStringNoMatch
- ;if there's nothing left to check,
- ; there are no non-blank characters
- dec di ;point back to the start of the
- ; next word, not byte
- repz scasw ;find the first non-blank character
- jz FindLastNonBlankInStringNoMatch
- ;there is no non-blank character in
- ; this string
- inc di ;undo 1 byte of SCASW's overrun, so
- ; this looks like SCASB's overrun
- cmp [di+2],al ;which of the 2 bytes we just
- ; checked was the last non-blank
- ; character?
- jz FindLastNonBlankInStringFound
- inc di ;the byte at the higher address was
- ; the last non-blank character, so
- ; adjust by 1 byte
- FindLastNonBlankInStringFound:
- inc di ;point to the non-blank character
- ; we just found, correcting for
- ; overrun of SCASB running from high
- ; addresses to low
- mov si,di ;return pointer to the last
- ; non-blank in SI
- cld
- ret
- FindLastNonBlankInStringNoMatch:
- sub si,si ;return that we didn't find a
- ; non-blank character
- cld
- ret
- ;
- Skip:
- call ZTimerOn
- mov si,offset TestString ;string to search
- call FindLastNonBlankInString ;search for the
- ; last non-blank
- ; character
- call ZTimerOff