1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31/ 32/ strlen(s) 33/ 34/ Returns the number of non-NULL bytes in string argument. 35/ 36/ 37/ Fast assembly language version of the following C-program strlen 38/ which represents the `standard' for the C-library. 39/ 40/ size_t 41/ strlen(const char *s) 42/ { 43/ const char *s0 = s + 1; 44/ 45/ while (*s++ != '\0') 46/ ; 47/ return (s - s0); 48/ } 49/ 50/ In this assembly language version, the following expression is used 51/ to check if a 32-bit word data contains a null byte or not: 52/ (((A & 0x7f7f7f7f) + 0x7f7f7f7f) | A) & 0x80808080 53/ If the above expression geneates a value other than 0x80808080, 54/ that means the 32-bit word data contains a null byte. 55/ 56 57#include "SYS.h" 58 59 ENTRY(strlen) 60 mov 4(%esp), %edx / src in %edx 61 mov %edx, %eax / cpy src to %eax 62 63 and $3, %edx / is src aligned? 64 jz countbytes 65 / work byte-wise until aligned 66 cmpb $0, (%eax) / is *src == 0 ? 67 jz done 68 inc %eax / increment src 69 cmp $3, %edx / if aligned, jump to word-wise check 70 jz countbytes 71 cmpb $0, (%eax) 72 jz done 73 inc %eax 74 cmp $2, %edx 75 jz countbytes 76 cmpb $0, (%eax) 77 jz done 78 inc %eax 79 80 .align 16 81 82countbytes: 83 mov (%eax), %ecx / load wrd 84 add $4, %eax / increment src by 4 (bytes in word) 85 lea -0x01010101(%ecx), %edx / (wrd - 0x01010101) 86 not %ecx / ~wrd 87 and $0x80808080, %ecx / ~wrd & 0x80808080 88 and %edx, %ecx / (wrd - 0x01010101) & ~wrd & 0x80808080 89 jz countbytes / if zero, no null byte found -- cont 90 91has_zero_byte: 92 bsfl %ecx, %ecx / find first set bit (null byte) 93 shr $3, %ecx / switch bit position to byte posn 94 lea -4(%eax, %ecx, 1), %eax / undo pre-increment and count bytes 95done: 96 sub 4(%esp), %eax / return (src - old_src) 97 ret 98 SET_SIZE(strlen) 99