; ; *** Listing 13-14 *** ; ; Copies a zero-terminated string to another string, ; optionally converting characters to uppercase. The ; decision as to whether to convert to uppercase is made ; once at the beginning of the subroutine; if conversion ; is not desired, the register containing the value of the ; start of the lowercase range is simply set to cause all ; tests for lowercase to fail. This avoids one test in the ; case where conversion to uppercase is desired, since the ; single test for the start of the lowercase range is able ; to perform both that test and the test for whether ; conversion is desired. ; jmp Skip ; SourceString label byte db 'This is a sample string, consisting of ' db 'both uppercase and lowercase characters.' db 0 DestinationString label byte db 100 dup (?) ; ; Copies a zero-terminated string to another string, ; optionally converting characters to uppercase. ; ; Input: ; DL = 1 if conversion to uppercase during copying is ; desired, 0 otherwise ; DS:SI = source string ; ES:DI = destination string ; ; Output: none ; ; Registers altered: AX, SI, DI ; ; Direction flag cleared ; ; Note: Does not handle strings that are longer than 64K ; bytes or cross segment boundaries. ; CopyAndConvert: cld mov ah,0ffh ;assume conversion to uppercase is ; not desired. In that case, this ; value will cause the initial ; lowercase test to fail (except ; when the character is 0FFh, but ; that's rare and will be rejected ; by the second lowercase test and dl,dl ;is conversion to uppercase desired? jz CopyAndConvertLoop ;no, AH is all set mov ah,'a' ;set the proper lower limit of the ; lowercase range CopyAndConvertLoop: lodsb ;get the next byte ; to check cmp al,ah ;less than 'a'? ; (If conversion ; isn't desired, ; AH is 0FFh, and ; this fails) jb CopyAndConvertUC ;yes, not lowercase cmp al,'z' ;greater than 'z'? ja CopyAndConvertUC ;yes, not lowercase and al,not 20h ;make it uppercase CopyAndConvertUC: stosb ;put the byte in the ; destination string and al,al ;was that the ; terminating zero? jnz CopyAndConvertLoop ;no, do next byte ret ; Skip: call ZTimerOn ; ; First, copy without converting to uppercase. ; mov di,seg DestinationString mov es,di mov di,offset DestinationString ;ES:DI points to the destination mov si,offset SourceString ;DS:SI points to the source sub dl,dl ;don't convert to uppercase call CopyAndConvert ;copy without converting ; to uppercase ; ; Now copy and convert to uppercase. ; mov di,offset DestinationString ;ES:DI points to the destination mov si,offset SourceString ;DS:SI points to the source mov dl,1 ;convert to uppercase this time call CopyAndConvert ;copy and convert to ; uppercase call ZTimerOff