📄 string.h
字号:
/* * OSV * Copyright (C) 2002 Ciprian DOSOFTEI <rocksoul@mail.com> * All rights reserved. * * http://backster.free.fr/osv * * This file is part of the OSV project. OSV is free software, also known as * "open source"; you can redistribute it and/or modify it under the terms * of the GNU General Public License (GPL), version 2, as published by the Free * Software Foundation (FSF). To explore alternate licensing terms, contact * the author at rocksoul@mail.com or +40740649907. * * OSV is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have * received a copy of the GPL along with OSV; see the file COPYING. If * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. */#ifndef INCSTRING#define INCSTRING#include <types.h>#define __HAVE_ARCH_STRCPYextern inline char * strcpy(char * dest, const char *src) { int d0, d1, d2; __asm__ __volatile__( "cld\n" "1:\tlodsb\n\t" "stosb\n\t" "testb %%al,%%al\n\t" "jne 1b" : "=&S" (d0), "=&D" (d1), "=&a" (d2) :"0" (src),"1" (dest) : "memory"); return dest;}#define __HAVE_ARCH_STRNCPYextern inline char * strncpy(char * dest, const char *src, size_t count) { int d0, d1, d2, d3; __asm__ __volatile__( "cld\n" "1:\tdecl %2\n\t" "js 2f\n\t" "lodsb\n\t" "stosb\n\t" "testb %%al,%%al\n\t" "jne 1b\n\t" "rep\n\t" "stosb\n" "2:" : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3) :"0" (src),"1" (dest),"2" (count) : "memory"); return dest;}#define __HAVE_ARCH_STRCATextern inline char * strcat(char * dest, const char * src) { int d0, d1, d2, d3; __asm__ __volatile__( "cld\n\t" "repne\n\t" "scasb\n\t" "decl %1\n" "1:\tlodsb\n\t" "stosb\n\t" "testb %%al,%%al\n\t" "jne 1b" : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory"); return dest;}#define __HAVE_ARCH_STRNCATextern inline char * strncat(char * dest, const char * src, size_t count) { int d0, d1, d2, d3; __asm__ __volatile__( "cld\n\t" "repne\n\t" "scasb\n\t" "decl %1\n\t" "movl %8,%3\n" "1:\tdecl %3\n\t" "js 2f\n\t" "lodsb\n\t" "stosb\n\t" "testb %%al,%%al\n\t" "jne 1b\n" "2:\txorl %2,%2\n\t" "stosb" : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) : "memory"); return dest;}#define __HAVE_ARCH_STRCMPextern inline int strcmp(const char * cs, const char * ct) { int d0, d1; register int __res; __asm__ __volatile__( "cld\n" "1:\tlodsb\n\t" "scasb\n\t" "jne 2f\n\t" "testb %%al,%%al\n\t" "jne 1b\n\t" "xorl %%eax,%%eax\n\t" "jmp 3f\n" "2:\tsbbl %%eax,%%eax\n\t" "orb $1,%%al\n" "3:" :"=a" (__res), "=&S" (d0), "=&D" (d1) :"1" (cs),"2" (ct)); return __res;}#define __HAVE_ARCH_STRNCMPextern inline int strncmp(const char * cs, const char * ct, size_t count) { register int __res; int d0, d1, d2; __asm__ __volatile__( "cld\n" "1:\tdecl %3\n\t" "js 2f\n\t" "lodsb\n\t" "scasb\n\t" "jne 3f\n\t" "testb %%al,%%al\n\t" "jne 1b\n" "2:\txorl %%eax,%%eax\n\t" "jmp 4f\n" "3:\tsbbl %%eax,%%eax\n\t" "orb $1,%%al\n" "4:" :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) :"1" (cs),"2" (ct),"3" (count)); return __res;}#define __HAVE_ARCH_STRCHRextern inline char * strchr(const char * s, int c) { int d0; register char * __res; __asm__ __volatile__( "cld\n\t" "movb %%al,%%ah\n" "1:\tlodsb\n\t" "cmpb %%ah,%%al\n\t" "je 2f\n\t" "testb %%al,%%al\n\t" "jne 1b\n\t" "movl $1,%1\n" "2:\tmovl %1,%0\n\t" "decl %0" :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); return __res;}#define __HAVE_ARCH_STRRCHRextern inline char * strrchr(const char * s, int c) { int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" "movb %%al,%%ah\n" "1:\tlodsb\n\t" "cmpb %%ah,%%al\n\t" "jne 2f\n\t" "leal -1(%%esi),%0\n" "2:\ttestb %%al,%%al\n\t" "jne 1b" :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); return __res;}#define __HAVE_ARCH_STRLENextern inline size_t strlen(const char * s) { int d0; register int __res; __asm__ __volatile__( "cld\n\t" "repne\n\t" "scasb\n\t" "notl %0\n\t" "decl %0" :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff)); return __res;}extern inline void * __memcpy(void * to, const void * from, size_t n) { int d0, d1, d2; __asm__ __volatile__( "cld\n\t" "rep ; movsl\n\t" "testb $2,%b4\n\t" "je 1f\n\t" "movsw\n" "1:\ttestb $1,%b4\n\t" "je 2f\n\t" "movsb\n" "2:" : "=&c" (d0), "=&D" (d1), "=&S" (d2) :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) : "memory"); return (to);}extern inline void * __constant_memcpy(void * to, const void * from, size_t n){ switch (n) { case 0: return to; case 1: *(unsigned char *)to = *(const unsigned char *)from; return to; case 2: *(unsigned short *)to = *(const unsigned short *)from; return to; case 3: *(unsigned short *)to = *(const unsigned short *)from; *(2+(unsigned char *)to) = *(2+(const unsigned char *)from); return to; case 4: *(unsigned long *)to = *(const unsigned long *)from; return to; case 6: /* for Ethernet addresses */ *(unsigned long *)to = *(const unsigned long *)from; *(2+(unsigned short *)to) = *(2+(const unsigned short *)from); return to; case 8: *(unsigned long *)to = *(const unsigned long *)from; *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); return to; case 12: *(unsigned long *)to = *(const unsigned long *)from; *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); return to; case 16: *(unsigned long *)to = *(const unsigned long *)from; *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); *(3+(unsigned long *)to) = *(3+(const unsigned long *)from); return to; case 20: *(unsigned long *)to = *(const unsigned long *)from; *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); *(3+(unsigned long *)to) = *(3+(const unsigned long *)from); *(4+(unsigned long *)to) = *(4+(const unsigned long *)from); return to; }#define COMMON(x) \__asm__ __volatile__( \ "cld\n\t" \ "rep ; movsl" \ x \ : "=&c" (d0), "=&D" (d1), "=&S" (d2) \ : "0" (n/4),"1" ((long) to),"2" ((long) from) \ : "memory");{ int d0, d1, d2; switch (n % 4) { case 0: COMMON(""); return to; case 1: COMMON("\n\tmovsb"); return to; case 2: COMMON("\n\tmovsw"); return to; default: COMMON("\n\tmovsw\n\tmovsb"); return to; }}#undef COMMON}#define __HAVE_ARCH_MEMCPY#define memcpy(t, f, n) \(__builtin_constant_p(n) ? \ __constant_memcpy((t),(f),(n)) : \ __memcpy((t),(f),(n)))#define __HAVE_ARCH_MEMMOVEextern inline void * memmove(void * dest, const void * src, size_t n) { int d0, d1, d2; if (dest<src) __asm__ __volatile__( "cld\n\t" "rep\n\t" "movsb" : "=&c" (d0), "=&S" (d1), "=&D" (d2) :"0" (n),"1" (src),"2" (dest) : "memory"); else __asm__ __volatile__( "std\n\t" "rep\n\t" "movsb\n\t" "cld" : "=&c" (d0), "=&S" (d1), "=&D" (d2) :"0" (n), "1" (n-1+(const char *)src), "2" (n-1+(char *)dest) :"memory"); return dest;}#define memcmp __builtin_memcmp#define __HAVE_ARCH_MEMCHRextern inline void * memchr(const void * cs, int c, size_t count) { int d0; register void * __res; if (!count) return NULL; __asm__ __volatile__( "cld\n\t" "repne\n\t" "scasb\n\t" "je 1f\n\t" "movl $1,%0\n" "1:\tdecl %0" :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); return __res;}extern inline void * __memset_generic(void * s, char c, size_t count) { int d0, d1; __asm__ __volatile__( "cld\n\t" "rep\n\t" "stosb" : "=&c" (d0), "=&D" (d1) :"a" (c),"1" (s),"0" (count) :"memory"); return s;}/* we might want to write optimized versions of these later */#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))/* * memset(x,0,y) is a reasonably common thing to do, so we want to fill * things 32 bits at a time even when we don't know the size of the * area at compile-time.. */extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count) { int d0, d1; __asm__ __volatile__( "cld\n\t" "rep ; stosl\n\t" "testb $2,%b3\n\t" "je 1f\n\t" "stosw\n" "1:\ttestb $1,%b3\n\t" "je 2f\n\t" "stosb\n" "2:" : "=&c" (d0), "=&D" (d1) :"a" (c), "q" (count), "0" (count/4), "1" ((long) s) :"memory"); return (s);}/* Added by Gertjan van Wingerde to make minix and sysv module work */#define __HAVE_ARCH_STRNLENextern inline size_t strnlen(const char * s, size_t count) { int d0; register int __res; __asm__ __volatile__( "movl %2,%0\n\t" "jmp 2f\n" "1:\tcmpb $0,(%0)\n\t" "je 3f\n\t" "incl %0\n" "2:\tdecl %1\n\t" "cmpl $-1,%1\n\t" "jne 1b\n" "3:\tsubl %2,%0" :"=a" (__res), "=&d" (d0) :"c" (s),"1" (count)); return __res;}/* end of additional stuff */extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count) { switch (count) { case 0: return s; case 1: *(unsigned char *)s = pattern; return s; case 2: *(unsigned short *)s = pattern; return s; case 3: *(unsigned short *)s = pattern; *(2+(unsigned char *)s) = pattern; return s; case 4: *(unsigned long *)s = pattern; return s; }#define COMMON(x) \__asm__ __volatile__("cld\n\t" \ "rep ; stosl" \ x \ : "=&c" (d0), "=&D" (d1) \ : "a" (pattern),"0" (count/4),"1" ((long) s) \ : "memory"){ int d0, d1; switch (count % 4) { case 0: COMMON(""); return s; case 1: COMMON("\n\tstosb"); return s; case 2: COMMON("\n\tstosw"); return s; default: COMMON("\n\tstosw\n\tstosb"); return s; }}#undef COMMON}#define __constant_c_x_memset(s, c, count) \(__builtin_constant_p(count) ? \ __constant_c_and_count_memset((s),(c),(count)) : \ __constant_c_memset((s),(c),(count)))#define __memset(s, c, count) \(__builtin_constant_p(count) ? \ __constant_count_memset((s),(c),(count)) : \ __memset_generic((s),(c),(count)))#define __HAVE_ARCH_MEMSET#define memset(s, c, count) \(__builtin_constant_p(c) ? \ __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \ __memset((s),(c),(count)))/* * find the first occurrence of byte 'c', or 1 past the area if none */#define __HAVE_ARCH_MEMSCANextern inline void * memscan(void * addr, int c, size_t size){ if (!size) return addr; __asm__("cld repnz; scasb jnz 1f dec %%edi1: " : "=D" (addr), "=c" (size) : "0" (addr), "1" (size), "a" (c)); return addr;}#define __HAVE_ARCH_MOVEDATAextern inline void movedata(unsigned src_seg, unsigned src_off, unsigned dst_seg, unsigned dst_off, size_t count){ __asm__("pushl %%ds\n" " movl %0,%%es\n" " movl %1,%%ds\n"/* xxx - handle overlapping src and dst */ " cld\n"/* take care of odd-length (byte) */ " shr %%ecx\n" " jnc 1f\n" " movsb\n"/* take care of word */ "1: shr %%ecx\n" " jnc 2f\n" " movsw\n"/* now copy 32 bits at a time */ "2: rep\n" " movsl\n" "popl %%ds\n" : : "m"(dst_seg), "m"(src_seg), "c"(count), "D"(dst_off), "S"(src_off));}#define bcopy(src,dst,len) memcpy((src),(dst),(len))#define bzero(b,len) memset((void *)(b),0,(size_t)(len))#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -