home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
platform
/
strchr.asm
< prev
next >
Wrap
Assembly Source File
|
1998-06-17
|
6KB
|
189 lines
page ,132
title strchr - search string for given character
;***
;strchr.asm - search a string for a given character
;
; Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines strchr() - search a string for a character
;
;*******************************************************************************
.xlist
include cruntime.inc
.list
page
;***
;char *strchr(string, chr) - search a string for a character
;
;Purpose:
; Searches a string for a given character, which may be the
; null character '\0'.
;
; Algorithm:
; char *
; strchr (string, chr)
; char *string, chr;
; {
; while (*string && *string != chr)
; string++;
; if (*string == chr)
; return(string);
; return((char *)0);
; }
;
;Entry:
; char *string - string to search in
; char chr - character to search for
;
;Exit:
; returns pointer to the first occurence of c in string
; returns NULL if chr does not occur in string
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************
CODESEG
found_bx:
lea eax,[edx - 1]
pop ebx ; restore ebx
ret ; _cdecl return
align 16
public strchr, __from_strstr_to_strchr
strchr proc
.FPO ( 0, 2, 0, 0, 0, 0 )
xor eax,eax
mov al,[esp + 8] ; al = chr (search char)
__from_strstr_to_strchr label proc
push ebx ; PRESERVE EBX
mov ebx,eax ; ebx = 0/0/0/chr
shl eax,8 ; eax = 0/0/chr/0
mov edx,[esp + 8] ; edx = buffer
test edx,3 ; test if string is aligned on 32 bits
jz short main_loop_start
str_misaligned: ; simple byte loop until string is aligned
mov cl,[edx]
inc edx
cmp cl,bl
je short found_bx
test cl,cl
jz short retnull_bx
test edx,3 ; now aligned ?
jne short str_misaligned
main_loop_start: ; set all 4 bytes of ebx to [chr]
or ebx,eax ; ebx = 0/0/chr/chr
push edi ; PRESERVE EDI
mov eax,ebx ; eax = 0/0/chr/chr
shl ebx,10h ; ebx = chr/chr/0/0
push esi ; PRESERVE ESI
or ebx,eax ; ebx = all 4 bytes = [chr]
; in the main loop (below), we are looking for chr or for EOS (end of string)
main_loop:
mov ecx,[edx] ; read dword (4 bytes)
mov edi,7efefeffh ; work with edi & ecx for looking for chr
mov eax,ecx ; eax = dword
mov esi,edi ; work with esi & eax for looking for EOS
xor ecx,ebx ; eax = dword xor chr/chr/chr/chr
add esi,eax
add edi,ecx
xor ecx,-1
xor eax,-1
xor ecx,edi
xor eax,esi
add edx,4
and ecx,81010100h ; test for chr
jnz short chr_is_found ; chr probably has been found
; chr was not found, check for EOS
and eax,81010100h ; is any flag set ??
jz short main_loop ; EOS was not found, go get another dword
and eax,01010100h ; is it in high byte?
jnz short retnull ; no, definitely found EOS, return failure
and esi,80000000h ; check was high byte 0 or 80h
jnz short main_loop ; it just was 80h in high byte, go get
; another dword
retnull:
pop esi
pop edi
retnull_bx:
pop ebx
xor eax,eax
ret ; _cdecl return
chr_is_found:
mov eax,[edx - 4] ; let's look one more time on this dword
cmp al,bl ; is chr in byte 0?
je short byte_0
test al,al ; test if low byte is 0
je retnull
cmp ah,bl ; is it byte 1
je short byte_1
test ah,ah ; found EOS ?
je retnull
shr eax,10h ; is it byte 2
cmp al,bl
je short byte_2
test al,al ; if in al some bits were set, bl!=bh
je retnull
cmp ah,bl
je short byte_3
test ah,ah
jz retnull
jmp short main_loop ; neither chr nor EOS found, go get
; another dword
byte_3:
pop esi
pop edi
lea eax,[edx - 1]
pop ebx ; restore ebx
ret ; _cdecl return
byte_2:
lea eax,[edx - 2]
pop esi
pop edi
pop ebx
ret ; _cdecl return
byte_1:
lea eax,[edx - 3]
pop esi
pop edi
pop ebx
ret ; _cdecl return
byte_0:
lea eax,[edx - 4]
pop esi ; restore esi
pop edi ; restore edi
pop ebx ; restore ebx
ret ; _cdecl return
strchr endp
end