page ,132 title strlen - return the length of a null-terminated string ;*** ;strlen.asm - contains strlen() routine ; ; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved. ; ;Purpose: ; strlen returns the length of a null-terminated string, ; not including the null byte itself. ; ;Revision History: ; 04-21-87 SKS Rewritten to be fast and small, added file header ; 05-18-88 SJM Add model-independent (large model) ifdef ; 08-02-88 SJM Add 32 bit code, use cruntime vs cmacros ; 08-23-88 JCR 386 cleanup ; 10-05-88 GJF Fixed off-by-2 error. ; 10-10-88 JCR Minor improvement ; 10-25-88 JCR General cleanup for 386-only code ; 10-26-88 JCR Re-arrange regs to avoid push/pop ebx ; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright. ; 05-10-91 GJF Back to _cdecl, sigh... ; 04-23-93 GJF Tuned for the 486. ; 06-16-93 GJF Added .FPO directive. ; 11-28-94 GJF New, faster version from Intel. ; 11-28-95 GJF Align main_loop on para boundary for 486 and P6 ; ;******************************************************************************* .xlist include cruntime.inc .list page ;*** ;strlen - return the length of a null-terminated string ; ;Purpose: ; Finds the length in bytes of the given string, not including ; the final null character. ; ; Algorithm: ; int strlen (const char * str) ; { ; int length = 0; ; ; while( *str++ ) ; ++length; ; ; return( length ); ; } ; ;Entry: ; const char * str - string whose length is to be computed ; ;Exit: ; EAX = length of the string "str", exclusive of the final null byte ; ;Uses: ; EAX, ECX, EDX ; ;Exceptions: ; ;******************************************************************************* CODESEG public strlen strlen proc .FPO ( 0, 1, 0, 0, 0, 0 ) string equ [esp + 4] mov ecx,string ; ecx -> string test ecx,3 ; test if string is aligned on 32 bits je short main_loop str_misaligned: ; simple byte loop until string is aligned mov al,byte ptr [ecx] inc ecx test al,al je short byte_3 test ecx,3 jne short str_misaligned add eax,dword ptr 0 ; 5 byte nop to align label below align 16 ; should be redundant main_loop: mov eax,dword ptr [ecx] ; read 4 bytes mov edx,7efefeffh add edx,eax xor eax,-1 xor eax,edx add ecx,4 test eax,81010100h je short main_loop ; found zero byte in the loop mov eax,[ecx - 4] test al,al ; is it byte 0 je short byte_0 test ah,ah ; is it byte 1 je short byte_1 test eax,00ff0000h ; is it byte 2 je short byte_2 test eax,0ff000000h ; is it byte 3 je short byte_3 jmp short main_loop ; taken if bits 24-30 are clear and bit ; 31 is set byte_3: lea eax,[ecx - 1] mov ecx,string sub eax,ecx ret byte_2: lea eax,[ecx - 2] mov ecx,string sub eax,ecx ret byte_1: lea eax,[ecx - 3] mov ecx,string sub eax,ecx ret byte_0: lea eax,[ecx - 4] mov ecx,string sub eax,ecx ret strlen endp end