7 ; Copies one string to another string, converting all characters to
\r
8 ; uppercase in the process, using a loop containing LODSB and STOSB.
\r
9 ; Adapted from Zen of Assembly Language, by Michael Abrash; not a
\r
10 ; standalone program, but designed to be used with the Zen timer from
\r
11 ; that book via the Zen timer's PZTIME.BAT batch file: ZTimerOn starts
\r
12 ; the clock, ZTimerOff stops it, and the test-bed program linked in by
\r
13 ; PZTIME.BAT starts the program, reports the results, and ends.
\r
15 jmp Skip ;skip over data in CS and subroutine
\r
17 SourceString label word ;sample string to copy
\r
18 db 'This space intentionally left not blank',0
\r
19 DestString db 100 dup (?) ;destination for copy
\r
21 ; Copies one zero-terminated string to another string,
\r
22 ; converting all characters to uppercase.
\r
23 ; Input: DS:SI = start of source string; DS:DI = start of destination buffer
\r
25 ; Registers altered: AX, BX, SI, DI, ES
\r
26 ; Direction flag cleared
\r
31 mov bl,'a' ;set up for fast register-register
\r
32 mov bh,'z' ; comparisons
\r
35 lodsb ;get next character and point to following character
\r
36 cmp al,bl ;below 'a'?
\r
37 jb IsUpper ;yes, not lowercase
\r
38 cmp al,bh ;above 'z'?
\r
39 ja IsUpper ;yes, not lowercase
\r
40 and al,not 20h ;is lowercase-make uppercase
\r
42 stosb ;put character into new string and point to
\r
43 ; following location
\r
44 and al,al ;is this the zero that marks end of the string?
\r
45 jnz StringUpperLoop ;no, do the next character
\r
48 ; Calls CopyStringUpper to copy & convert SourceString->DestString.
\r
50 call ZTimerOn ;start timing
\r
51 mov si,offset SourceString ;point SI to the string to copy from
\r
52 mov di,offset DestString ;point DI to the string to copy to
\r
53 call CopyStringUpper ;copy & convert to uppercase
\r
54 call ZTimerOff ;stop timing
\r
59 ; Copies one string to another string, converting all characters to
\r
60 ; uppercase in the process, using no string instructions.
\r
61 ; Not a standalone program, but designed to be used with the Zen
\r
62 ; timer, as described in Listing 1.
\r
64 jmp Skip ;skip over data in CS and subroutine
\r
66 SourceString label word ;sample string to copy
\r
67 db 'This space intentionally left not blank',0
\r
68 DestString db 100 dup (?) ;destination for copy
\r
70 ; Copies one zero-terminated string to another string,
\r
71 ; converting all characters to uppercase.
\r
72 ; Input: DS:SI = start of source string; DS:DI = start of destination string
\r
74 ; Registers altered: AL, BX, SI, DI
\r
77 mov bl,'a' ;set up for fast register-register
\r
78 mov bh,'z' ; comparisons
\r
80 mov al,[si] ;get the next character and
\r
81 inc si ; point to the following character
\r
82 cmp al,bl ;below 'a'?
\r
83 jb IsUpper ;yes, not lowercase
\r
84 cmp al,bh ;above 'z'?
\r
85 ja IsUpper ;yes, not lowercase
\r
86 and al,not 20h ;is lowercase-make uppercase
\r
88 mov [di],al ;put the character into the new string and
\r
89 inc di ; point to the following location
\r
90 and al,al ;is this the zero that marks the end of the string?
\r
91 jnz StringUpperLoop ;no, do the next character
\r
94 ; Calls CopyStringUpper to copy & convert SourceString->DestString.
\r
97 mov si,offset SourceString ;point SI to the string to copy from
\r
98 mov di,offset DestString ;point DI to the string to copy to
\r
99 call CopyStringUpper ;copy & convert to uppercase
\r
105 ; Clears a buffer using MOV/ADD in a loop.
\r
106 ; Not a standalone program, but designed to be used with the Zen
\r
107 ; timer, as described in Listing 1.
\r
109 mov dx,2 ;repeat the test code twice, to make
\r
110 ; sure it's in the cache (if there is one)
\r
111 mov bx,dx ;distance from the start of one word
\r
112 ; to the start of the next
\r
113 sub ax,ax ;set buffer to zeroes
\r
115 mov cx,1024 ;clear 1024 words starting at address
\r
116 mov di,8000h ; DS:8000h (this is just unused memory
\r
117 ; past the end of the program)
\r
118 call ZTimerOn ;start timing (resets timer to 0)
\r
120 mov [di],ax ;clear the current word
\r
121 add di,bx ;point to the next word
\r
122 dec cx ;count off words to clear until none
\r
123 jnz StoreLoop ; remain
\r
124 call ZTimerOff ;stop timing
\r
125 dec dx ;count off passes through test code
\r
126 jz StoreDone ;that was the second pass; we're done
\r
127 jmp TestTwiceLoop ;that was first pass; do second pass with all
\r
128 ; instructions and data in the cache
\r
134 ; Clears a buffer using MOV/ADD in an unrolled loop.
\r
135 ; Not a standalone program, but designed to be used with the Zen
\r
136 ; timer, as described in Listing 1.
\r
138 mov dx,2 ;repeat the test code twice, to make
\r
139 ; sure it's in the cache (if there is one)
\r
140 mov bx,dx ;distance from the start of one word
\r
141 ; to the start of the next
\r
142 sub ax,ax ;set buffer to zeroes
\r
144 mov si,1024 ;clear 1024 words starting at address
\r
145 mov di,8000h ; DS:8000h (this is just unused memory
\r
146 ; past the end of the program)
\r
147 call ZTimerOn ;start timing (resets timer to 0)
\r
148 mov cl,4 ;divide the count of words to clear by
\r
149 shr si,cl ; 16, because we'll clear 16 words
\r
150 ; each time through the loop
\r
152 REPT 16 ;clear 16 words in a row without looping
\r
153 mov [di],ax ;clear the current word
\r
154 add di,bx ;point to the next word
\r
156 dec si ;count off blocks of 16 words to clear
\r
157 jnz StoreLoop ; until none remain
\r
158 call ZTimerOff ;stop timing
\r
159 dec dx ;count off passes through test code
\r
160 jz StoreDone ;that was the second pass; we're done
\r
161 jmp TestTwiceLoop ;that was the first pass; do the second pass
\r
162 ; with all instructions and data in the cache
\r