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