Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
32
09-03.md
32
09-03.md
|
|
@ -5,19 +5,19 @@
|
|||
Listing 9.1 implements the scan-on-first-character approach. Listing 9.2
|
||||
scans for whatever character the caller specifies. Listing 9.3 is a test
|
||||
program used to compare the two approaches. How much difference does
|
||||
Rob’s revelation make? Plenty. Even when the entire C function call to
|
||||
Rob's revelation make? Plenty. Even when the entire C function call to
|
||||
**FindString** is timed—**strlen** calls, parameter pushing, calling,
|
||||
setup, and all—the version of **FindString** in Listing 9.2, which is
|
||||
directed by Listing 9.3 to scan for the infrequently-occurring “Q,” is
|
||||
directed by Listing 9.3 to scan for the infrequently-occurring "Q," is
|
||||
about 40 percent faster on a 20 MHz cached 386 for the test search of
|
||||
Listing 9.3 than is the version of **FindString** in Listing 9.1, which
|
||||
always scans for the first character, in this case “E.” However, when
|
||||
always scans for the first character, in this case "E." However, when
|
||||
only the search loops (the code that actually does the searching) in the
|
||||
two versions of **FindString** are compared, Listing 9.2 is more than
|
||||
*twice* as fast as Listing 9.1—a remarkable improvement over code that
|
||||
already uses **REPNZ SCASB** and **REPZ CMPS**.
|
||||
|
||||
What I like so much about Rob’s approach is that it demonstrates that
|
||||
What I like so much about Rob's approach is that it demonstrates that
|
||||
optimization involves much more than instruction selection and cycle
|
||||
counting. Listings 9.1 and 9.2 use pretty much the same instructions,
|
||||
and even use the same approach of scanning with **REPNZ SCASB** and
|
||||
|
|
@ -59,9 +59,9 @@ using **REPZ CMPS** to check scanning matches.
|
|||
.code
|
||||
public _FindString
|
||||
_FindStringprocnear
|
||||
push bp ;preserve caller’s stack frame
|
||||
push bp ;preserve caller's stack frame
|
||||
mov bp,sp ;point to our stack frame
|
||||
push si ;preserve caller’s register variables
|
||||
push si ;preserve caller's register variables
|
||||
push di
|
||||
cld ;make string instructions increment pointers
|
||||
mov si,[bp+SearchString] ;pointer to string to search for
|
||||
|
|
@ -80,12 +80,12 @@ using **REPZ CMPS** to check scanning matches.
|
|||
mov di,[bp+Buffer] ;point ES:DI to buffer to search thru
|
||||
lodsb ;put the first byte of the search string in AL
|
||||
mov bp,si ;set aside pointer to the second search byte
|
||||
dec bx ;don’t need to compare the first byte of the
|
||||
; string with CMPS; we’ll do it with SCAS
|
||||
dec bx ;don't need to compare the first byte of the
|
||||
; string with CMPS; we'll do it with SCAS
|
||||
FindStringLoop:
|
||||
mov cx,dx ;put remaining buffer search length in CX
|
||||
repnz scasb ;scan for the first byte of the string
|
||||
jnz FindStringNotFound ;not found, so there’s no match
|
||||
jnz FindStringNotFound ;not found, so there's no match
|
||||
;found, so we have a potential match-check the
|
||||
; rest of this candidate location
|
||||
push di ;remember the address of the next byte to scan
|
||||
|
|
@ -96,14 +96,14 @@ using **REPZ CMPS** to check scanning matches.
|
|||
shr cx,1 ;convert to word for faster search
|
||||
jnc FindStringWord ;do word search if no odd byte
|
||||
cmpsb ;compare the odd byte
|
||||
jnz FindStringNoMatch ;odd byte doesn’t match, so we
|
||||
; haven’t found the search string here
|
||||
jnz FindStringNoMatch ;odd byte doesn't match, so we
|
||||
; haven't found the search string here
|
||||
FindStringWord:
|
||||
jcxz FindStringFound ;test whether we’ve already checked
|
||||
jcxz FindStringFound ;test whether we've already checked
|
||||
; the whole string; if so, this is a match
|
||||
; bytes long; if so, we’ve found a match
|
||||
; bytes long; if so, we've found a match
|
||||
repz cmpsw ;check the rest of the string a word at a time
|
||||
jz FindStringFound ;it’s a match
|
||||
jz FindStringFound ;it's a match
|
||||
FindStringNoMatch:
|
||||
pop di ;get back pointer to the next byte to scan
|
||||
and dx,dx ;is there anything left to check?
|
||||
|
|
@ -117,9 +117,9 @@ using **REPZ CMPS** to check scanning matches.
|
|||
; address of the byte after the start of the
|
||||
; potential match)
|
||||
FindStringDone:
|
||||
pop di ;restore caller’s register variables
|
||||
pop di ;restore caller's register variables
|
||||
pop si
|
||||
pop bp ;restore caller’s stack frame
|
||||
pop bp ;restore caller's stack frame
|
||||
ret
|
||||
_FindStringendp
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue