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/ strcpy(s1, s2) 33/ 34/ Copies string s2 to s1. s1 must be large enough. 35/ Returns s1 36/ 37/ 38/ Fast assembly language version of the following C-program strcpy 39/ which represents the `standard' for the C-library. 40/ 41/ char * 42/ strcpy(char *s1, const char *s2) 43/ { 44/ char *os1 = s1; 45/ 46/ while (*s1++ = *s2++) 47/ ; 48/ return (os1); 49/ } 50/ 51/ In this assembly language version, the following expression is used 52/ to check if a 32-bit word data contains a null byte or not: 53/ (((A & 0x7f7f7f7f) + 0x7f7f7f7f) | A) & 0x80808080 54/ If the above expression geneates a value other than 0x80808080, 55/ that means the 32-bit word data contains a null byte. 56/ 57 58#include "SYS.h" 59 60 ENTRY(strcpy) 61 push %edi / save reg as per calling cvntn 62 mov 12(%esp), %ecx / src ptr 63 mov 8(%esp), %edi / dst ptr 64 mov %ecx, %eax / src 65 sub %edi, %ecx / src - dst 66 and $3, %eax / check src alignment 67 jz load 68 sub $4, %eax 69 70byte_loop: 71 movb (%edi, %ecx, 1), %dl / load src byte 72 movb %dl, (%edi) / load dest byte 73 inc %edi / increment src and dest 74 testb %dl, %dl / is src zero? 75 jz done 76 inc %eax / check src alignment 77 jnz byte_loop 78 jmp load 79 80store: 81 mov %eax, (%edi) / store word 82 add $4, %edi / incrment src and dest by 4 83load: 84 mov (%edi, %ecx, 1), %eax / load word 85 lea -0x01010101(%eax), %edx / (word - 0x01010101) 86 not %eax / ~word 87 and %eax, %edx / (word - 0x01010101) & ~word 88 not %eax / word 89 and $0x80808080, %edx / (wd - 0x01010101) & ~wd & 0x80808080 90 jz store / store word w/o zero byte 91 92has_zero_byte: 93 movb %al, (%edi) / store first byte 94 testb %al, %al / check first byte for zero 95 jz done 96 movb %ah, 1(%edi) / continue storing and checking 97 testb %ah, %ah 98 jz done 99 shr $16, %eax / grab last two bytes 100 movb %al, 2(%edi) 101 testb %al, %al 102 jz done 103 movb %ah, 3(%edi) 104done: 105 mov 8(%esp), %eax / return ptr to dest 106 pop %edi / restore as per calling cvntn 107 ret 108 SET_SIZE(strcpy) 109