#ifndef _STRING_H_
#define _STRING_H_

#ifndef NULL
#define NULL ((void *) 0)
#endif

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif

extern char *strerror (int errno);

/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* (C) 1991 Linus Torvalds
*/
/*
* ַͷļǶʽַʹgcc ʱͬʱ
* ٶds=es=ݿռ䣬ӦǳġַǾֹд
* ŻģǺstrtokstrstrstr[c]spnӦȴ
* ô⡣еĲ϶ʹüĴɵģʹúࡣ
* еطʹַָʹô롰΢?
*
* (C) 1991 Linus Torvalds
*/

//// һַ(src)һַ(dest)ֱNULL ַֹͣ
// dest - Ŀַָ룬src - Դַָ롣
// %0 - esi(src)%1 - edi(dest)
extern inline char *
strcpy (char *dest, const char *src)
{
  __asm__ ("cld\n"		// 巽λ
	   "1:\tlodsb\n\t"	// DS:[esi]1 ֽ??alesi
	   "stosb\n\t"		// 洢ֽal??ES:[edi]edi
	   "testb %%al,%%al\n\t"	// մ洢ֽ0
	   "jne 1b"		// ת1 
::"S" (src), "D" (dest):"si", "di", "ax");
  return dest;			// Ŀַָ롣
}

//// Դַcount ֽڵĿַ
// ԴСcount ֽڣ͸ӿַ(NULL)Ŀַ
// dest - Ŀַָ룬src - Դַָ룬count - ֽ
// %0 - esi(src)%1 - edi(dest)%2 - ecx(count)
extern inline char *
strncpy (char *dest, const char *src, int count)
{
  __asm__ ("cld\n"		// 巽λ
	   "1:\tdecl %2\n\t"	// Ĵecx--count--
	   "js 2f\n\t"		// count<0 ǰת2
	   "lodsb\n\t"		// ȡds:[esi]1 ֽ??alesi++
	   "stosb\n\t"		// 洢ֽ??es:[edi]edi++
	   "testb %%al,%%al\n\t"	// ֽ0
	   "jne 1b\n\t"		// ǣǰת1 
	   "rep\n\t"		// ĿĴдʣĿַ
"stosb\n" "2:"::"S" (src), "D" (dest), "c" (count):"si", "di", "ax",
	   "cx");
  return dest;			// Ŀַָ롣
}

//// ԴַĿַĩβ
// dest - Ŀַָ룬src - Դַָ롣
// %0 - esi(src)%1 - edi(dest)%2 - eax(0)%3 - ecx(-1)
extern inline char *
strcat (char *dest, const char *src)
{
  __asm__ ("cld\n\t"		// 巽λ
	   "repne\n\t"		// Ƚal es:[edi]ֽڣedi++
	   "scasb\n\t"		// ֱҵĿĴ0 ֽڣʱedi Ѿָ1 ֽڡ
	   "decl %1\n"		// es:[edi]ָ0 ֵֽڡ
	   "1:\tlodsb\n\t"	// ȡԴַֽds:[esi]??alesi++
	   "stosb\n\t"		// ֽڴ浽es:[edi]edi++
	   "testb %%al,%%al\n\t"	// ֽ0
	   "jne 1b"		// ǣת1 
::"S" (src), "D" (dest), "a" (0), "c" (0xffffffff):"si", "di", "ax",
	   "cx");
  return dest;			// Ŀַָ롣
}

//// Դַcount ֽڸƵĿַĩβһַ
// dest - Ŀַsrc - Դַcount - Ƶֽ
// %0 - esi(src)%1 - edi(dest)%2 - eax(0)%3 - ecx(-1)%4 - (count)
extern inline char *
strncat (char *dest, const char *src, int count)
{
  __asm__ ("cld\n\t"		// 巽λ
	   "repne\n\t"		// Ƚal es:[edi]ֽڣedi++
	   "scasb\n\t"		// ֱҵĿĴĩ0 ֵֽڡ
	   "decl %1\n\t"	// edi ָ0 ֵֽڡ
	   "movl %4,%3\n"	// ֽ??ecx
	   "1:\tdecl %3\n\t"	// ecx--0 ʼ
	   "js 2f\n\t"		// ecx <0 ?ǰת2 
	   "lodsb\n\t"		// ȡds:[esi]ֽ??alesi++
	   "stosb\n\t"		// 洢es:[edi]edi++
	   "testb %%al,%%al\n\t"	// ֵֽΪ0
	   "jne 1b\n"		// ת1 ơ
	   "2:\txorl %2,%2\n\t"	// al 㡣
	   "stosb"		// 浽es:[edi]
::"S" (src), "D" (dest), "a" (0), "c" (0xffffffff), "g" (count):"si", "di", "ax",
	   "cx");
  return dest;			// Ŀַָ롣
}

//// һַһַбȽϡ
// cs - ַ1ct - ַ2
// %0 - eax(__res)ֵ%1 - edi(cs)ַ1 ָ룬%2 - esi(ct)ַ2 ָ롣
// أ1 > 2򷵻11 = 2򷵻01 < 2򷵻-1
extern inline int
strcmp (const char *cs, const char *ct)
{
  register int __res __asm__ ("ax");	// __res ǼĴ(eax)
  __asm__ ("cld\n"		// 巽λ
	   "1:\tlodsb\n\t"	// ȡַ2 ֽds:[esi]??alesi++
	   "scasb\n\t"		// al ַ1 ֽes:[edi]Ƚϣedi++
	   "jne 2f\n\t"		// ȣǰת2
	   "testb %%al,%%al\n\t"	// ֽ0 ֵַֽβ
	   "jne 1b\n\t"		// ǣת1Ƚϡ
	   "xorl %%eax,%%eax\n\t"	// ǣ򷵻ֵeax 㣬
	   "jmp 3f\n"		// ǰת3
	   "2:\tmovl $1,%%eax\n\t"	// eax 1
	   "jl 3f\n\t"		// ǰȽд2 ַ<1 ַ򷵻ֵ
	   "negl %%eax\n"	// eax = -eaxظֵ
"3:": "=a" (__res): "D" (cs), "S" (ct):"si", "di");
  return __res;			// رȽϽ
}

//// ַ1 ַ2 ǰcount ַбȽϡ
// cs - ַ1ct - ַ2count - Ƚϵַ
// %0 - eax(__res)ֵ%1 - edi(cs)1 ָ룬%2 - esi(ct)2 ָ룬%3 - ecx(count)
// أ1 > 2򷵻11 = 2򷵻01 < 2򷵻-1
extern inline int
strncmp (const char *cs, const char *ct, int count)
{
  register int __res __asm__ ("ax");	// __res ǼĴ(eax)
  __asm__ ("cld\n"		// 巽λ
	   "1:\tdecl %3\n\t"	// count--
	   "js 2f\n\t"		// count<0ǰת2
	   "lodsb\n\t"		// ȡ2 ַds:[esi]??alesi++
	   "scasb\n\t"		// Ƚal 봮1 ַes:[edi]edi++
	   "jne 3f\n\t"		// ȣǰת3
	   "testb %%al,%%al\n\t"	// ַNULL ַ
	   "jne 1b\n"		// ǣת1Ƚϡ
	   "2:\txorl %%eax,%%eax\n\t"	// NULL ַeax 㣨ֵ
	   "jmp 4f\n"		// ǰת4
	   "3:\tmovl $1,%%eax\n\t"	// eax 1
	   "jl 4f\n\t"		// ǰȽд2 ַ<2 ַ򷵻1
	   "negl %%eax\n"	// eax = -eaxظֵ
"4:": "=a" (__res): "D" (cs), "S" (ct), "c" (count):"si", "di",
	   "cx");
  return __res;			// رȽϽ
}

//// ַѰҵһƥַ
// s - ַc - Ѱҵַ
// %0 - eax(__res)%1 - esi(ַָs)%2 - eax(ַc)
// أַеһγƥַָ롣ûҵƥַ򷵻ؿָ롣
extern inline char *
strchr (const char *s, char c)
{
  register char *__res __asm__ ("ax");	// __res ǼĴ(eax)
  __asm__ ("cld\n\t"		// 巽λ
	   "movb %%al,%%ah\n"	// ȽַƵah
	   "1:\tlodsb\n\t"	// ȡַַds:[esi]??alesi++
	   "cmpb %%ah,%%al\n\t"	// ַַal ַָah Ƚϡ
	   "je 2f\n\t"		// ȣǰת2 
	   "testb %%al,%%al\n\t"	// al ַNULL ַ𣿣ַβ
	   "jne 1b\n\t"		// ǣת1Ƚϡ
	   "movl $1,%1\n"	// ǣ˵ûҵƥַesi 1
	   "2:\tmovl %1,%0\n\t"	// ָƥַһֽڴֵָeax
	   "decl %0"		// ָΪָƥַ
: "=a" (__res): "S" (s), "" (c):"si");
  return __res;			// ָ롣
}

//// Ѱַַָһγֵĵطַ
// s - ַc - Ѱҵַ
// %0 - edx(__res)%1 - edx(0)%2 - esi(ַָs)%3 - eax(ַc)
// أַһγƥַָ롣ûҵƥַ򷵻ؿָ롣
extern inline char *
strrchr (const char *s, char c)
{
  register char *__res __asm__ ("dx");	// __res ǼĴ(edx)
  __asm__ ("cld\n\t"		// 巽λ
	   "movb %%al,%%ah\n"	// ѰҵַƵah
	   "1:\tlodsb\n\t"	// ȡַַds:[esi]??alesi++
	   "cmpb %%ah,%%al\n\t"	// ַַal ַָah Ƚϡ
	   "jne 2f\n\t"		// ȣǰת2 
	   "movl %%esi,%0\n\t"	// ַָ뱣浽edx С
	   "decl %0\n"		// ָһλַָƥַ
	   "2:\ttestb %%al,%%al\n\t"	// Ƚϵַ0 𣨵ַβ
	   "jne 1b"		// ת1 Ƚϡ
: "=d" (__res): "" (0), "S" (s), "a" (c):"ax", "si");
  return __res;			// ָ롣
}

//// ַ1 Ѱҵ1 ַУַеκַַ2 С
// cs - ַ1 ָ룬ct - ַ2 ָ롣
// %0 - esi(__res)%1 - eax(0)%2 - ecx(-1)%3 - esi(1 ָcs)%4 - (2 ָct)
// ַ1 аַ2 κַ׸ַеĳֵ
extern inline int
strspn (const char *cs, const char *ct)
{
  register char *__res __asm__ ("si");	// __res ǼĴ(esi)
  __asm__ ("cld\n\t"		// 巽λ
	   "movl %4,%%edi\n\t"	// ȼ㴮2 ĳȡ2 ָedi С
	   "repne\n\t"		// Ƚal(0)봮2 еַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽ(ecx 𲽵ݼ)
	   "notl %%ecx\n\t"	// ecx ÿλȡ
	   "decl %%ecx\n\t"	// ecx--ô2 ĳֵ
	   "movl %%ecx,%%edx\n"	// 2 ĳֵݷedx С
	   "1:\tlodsb\n\t"	// ȡ1 ַds:[esi]??alesi++
	   "testb %%al,%%al\n\t"	// ַ0 ֵ𣨴1 β
	   "je 2f\n\t"		// ǣǰת2 
	   "movl %4,%%edi\n\t"	// ȡ2 ͷָedi С
	   "movl %%edx,%%ecx\n\t"	// ٽ2 ĳֵecx С
	   "repne\n\t"		// Ƚal 봮2 ַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽϡ
	   "je 1b\n"		// ȣת1 
	   "2:\tdecl %0"	// esi--ָһڴ2 еַ
: "=S" (__res): "a" (0), "c" (0xffffffff), "" (cs), "g" (ct):"ax", "cx", "dx",
	   "di");
  return __res - cs;		// ַеĳֵ
}

//// Ѱַ1 вַ2 κַ׸ַС
// cs - ַ1 ָ룬ct - ַ2 ָ롣
// %0 - esi(__res)%1 - eax(0)%2 - ecx(-1)%3 - esi(1 ָcs)%4 - (2 ָct)
// ַ1 вַ2 κַ׸ַеĳֵ
extern inline int
strcspn (const char *cs, const char *ct)
{
  register char *__res __asm__ ("si");	// __res ǼĴ(esi)
  __asm__ ("cld\n\t"		// 巽λ
	   "movl %4,%%edi\n\t"	// ȼ㴮2 ĳȡ2 ָedi С
	   "repne\n\t"		// Ƚal(0)봮2 еַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽ(ecx 𲽵ݼ)
	   "notl %%ecx\n\t"	// ecx ÿλȡ
	   "decl %%ecx\n\t"	// ecx--ô2 ĳֵ
	   "movl %%ecx,%%edx\n"	// 2 ĳֵݷedx С
	   "1:\tlodsb\n\t"	// ȡ1 ַds:[esi]??alesi++
	   "testb %%al,%%al\n\t"	// ַ0 ֵ𣨴1 β
	   "je 2f\n\t"		// ǣǰת2 
	   "movl %4,%%edi\n\t"	// ȡ2 ͷָedi С
	   "movl %%edx,%%ecx\n\t"	// ٽ2 ĳֵecx С
	   "repne\n\t"		// Ƚal 봮2 ַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽϡ
	   "jne 1b\n"		// ȣת1 
	   "2:\tdecl %0"	// esi--ָһڴ2 еַ
: "=S" (__res): "a" (0), "c" (0xffffffff), "" (cs), "g" (ct):"ax", "cx", "dx",
	   "di");
  return __res - cs;		// ַеĳֵ
}

//// ַ1 Ѱ׸ַ2 еκַ
// cs - ַ1 ָ룬ct - ַ2 ָ롣
// %0 -esi(__res)%1 -eax(0)%2 -ecx(0xffffffff)%3 -esi(1 ָcs)%4 -(2 ָct)
// ַ1 ׸ַ2 ַָ롣
extern inline char *
strpbrk (const char *cs, const char *ct)
{
  register char *__res __asm__ ("si");	// __res ǼĴ(esi)
  __asm__ ("cld\n\t"		// 巽λ
	   "movl %4,%%edi\n\t"	// ȼ㴮2 ĳȡ2 ָedi С
	   "repne\n\t"		// Ƚal(0)봮2 еַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽ(ecx 𲽵ݼ)
	   "notl %%ecx\n\t"	// ecx ÿλȡ
	   "decl %%ecx\n\t"	// ecx--ô2 ĳֵ
	   "movl %%ecx,%%edx\n"	// 2 ĳֵݷedx С
	   "1:\tlodsb\n\t"	// ȡ1 ַds:[esi]??alesi++
	   "testb %%al,%%al\n\t"	// ַ0 ֵ𣨴1 β
	   "je 2f\n\t"		// ǣǰת2 
	   "movl %4,%%edi\n\t"	// ȡ2 ͷָedi С
	   "movl %%edx,%%ecx\n\t"	// ٽ2 ĳֵecx С
	   "repne\n\t"		// Ƚal 봮2 ַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽϡ
	   "jne 1b\n\t"		// ȣת1 
	   "decl %0\n\t"	// esi--ָһڴ2 еַ
	   "jmp 3f\n"		// ǰת3 
	   "2:\txorl %0,%0\n"	// ûҵģֵΪNULL
"3:": "=S" (__res): "a" (0), "c" (0xffffffff), "" (cs), "g" (ct):"ax", "cx", "dx",
	   "di");
  return __res;			// ֵָ
}

//// ַ1 Ѱ׸ƥַ2 ַ
// cs - ַ1 ָ룬ct - ַ2 ָ롣
// %0 -eax(__res)%1 -eax(0)%2 -ecx(0xffffffff)%3 -esi(1 ָcs)%4 -(2 ָct)
// أַ1 ׸ƥַ2 ַָ롣
extern inline char *
strstr (const char *cs, const char *ct)
{
  register char *__res __asm__ ("ax");	// __res ǼĴ(eax)
  __asm__ ("cld\n\t" \		// 巽λ
	   "movl %4,%%edi\n\t"	// ȼ㴮2 ĳȡ2 ָedi С
	   "repne\n\t"		// Ƚal(0)봮2 еַes:[edi]edi++
	   "scasb\n\t"		// ȾͼȽ(ecx 𲽵ݼ)
	   "notl %%ecx\n\t"	// ecx ÿλȡ
	   "decl %%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
/* ע⣡ΪգZ ־ */// ô2 ĳֵ
	   "movl %%ecx,%%edx\n"	// 2 ĳֵݷedx С
	   "1:\tmovl %4,%%edi\n\t"	// ȡ2 ͷָedi С
	   "movl %%esi,%%eax\n\t"	// 1 ָ븴Ƶeax С
	   "movl %%edx,%%ecx\n\t"	// ٽ2 ĳֵecx С
	   "repe\n\t"		// Ƚϴ1 ʹ2 ַ(ds:[esi],es:[edi])esi++,edi++
	   "cmpsb\n\t"		// ӦַȾһֱȽȥ
	   "je 2f\n\t"		/* also works for empty string, see above */
/* ԿմͬЧ */// ȫȣת2
	   "xchgl %%eax,%%esi\n\t"	// 1 ͷָ??esiȽϽĴ1 ָ??eax
	   "incl %%esi\n\t"	// 1 ͷָָһַ
	   "cmpb $0,-1(%%eax)\n\t"	// 1 ָ(eax-1)ָֽ0 
	   "jne 1b\n\t"		// ת1Ӵ1 ĵ2 ַʼȽϡ
	   "xorl %%eax,%%eax\n\t"	// eaxʾûҵƥ䡣
"2:": "=a" (__res): "" (0), "c" (0xffffffff), "S" (cs), "g" (ct):"cx", "dx", "di",
	   "si");
  return __res;			// رȽϽ
}

//// ַȡ
// s - ַ
// %0 - ecx(__res)%1 - edi(ַָs)%2 - eax(0)%3 - ecx(0xffffffff)
// أַĳȡ
extern inline int
strlen (const char *s)
{
  register int __res __asm__ ("cx");	// __res ǼĴ(ecx)
  __asm__ ("cld\n\t"		// 巽λ
	   "repne\n\t"		// al(0)ַַes:[edi]Ƚϣ
	   "scasb\n\t"		// ȾһֱȽϡ
	   "notl %0\n\t"	// ecx ȡ
	   "decl %0"		// ecx--ַóֵ
: "=c" (__res): "D" (s), "a" (0), "" (0xffffffff):"di");
  return __res;			// ֵַ
}

extern char *___strtok;		// ʱָ汻ַ1(s)ָ롣

//// ַ2 еַַ1 ָɱ(tokern)С
// 1 ǰ(token)Уɷַָ2 еһַֿ
// һεstrtok()ʱַָ1 е1 token ַָ룬ڷtoken ʱ
// һnull ַдָʹnull Ϊַ1 ĵãַɨַ1
// ֱûtoken ΪֹڲͬĵùУָ2 Բͬ
// s - ַ1ct - ַָ2
// %0 - ebx(__res)%1 - esi(__strtok)
// 룺%2 - ebx(__strtok)%3 - esi(ַ1 ָs)%4 - ַ2 ָct
// أַs е1 tokenûҵtoken򷵻һnull ָ롣
// ʹַs ָΪnull ĵãԭַs һtoken
extern inline char *
strtok (char *s, const char *ct)
{
  register char *__res __asm__ ("si");
  __asm__ ("testl %1,%1\n\t"	// Ȳesi(ַ1 ָs)ǷNULL
	   "jne 1f\n\t"		// ǣ״εñת1
	   "testl %0,%0\n\t"	// NULLʾ˴Ǻãebx(__strtok)
	   "je 8f\n\t"		// ebx ָNULLܴת
	   "movl %0,%1\n"	// ebx ָ븴Ƶesi
	   "1:\txorl %0,%0\n\t"	// ebx ָ롣
	   "movl $-1,%%ecx\n\t"	// ecx = 0xffffffff
	   "xorl %%eax,%%eax\n\t"	// eax
	   "cld\n\t"		// 巽λ
	   "movl %4,%%edi\n\t"	// ַ2 ĳȡedi ַָ2
	   "repne\n\t"		// al(0)es:[edi]Ƚϣedi++
	   "scasb\n\t"		// ֱҵַ2 Ľnull ַecx==0
	   "notl %%ecx\n\t"	// ecx ȡ
	   "decl %%ecx\n\t"	// ecx--õַ2 ĳֵ
	   "je 7f\n\t"		/* empty delimeter-string */
/* ַָ */// 2 Ϊ0ת7
	   "movl %%ecx,%%edx\n"	// 2 ݴedx
	   "2:\tlodsb\n\t"	// ȡ1 ַds:[esi]??alesi++
	   "testb %%al,%%al\n\t"	// ַΪ0 ֵ(1 )
	   "je 7f\n\t"		// ǣת7
	   "movl %4,%%edi\n\t"	// edi ٴָ2 ס
	   "movl %%edx,%%ecx\n\t"	// ȡ2 ĳֵecx
	   "repne\n\t"		// al д1 ַ봮2 ַȽϣ
	   "scasb\n\t"		// жϸַǷΪָ
	   "je 2b\n\t"		// ڴ2 ҵַָͬת2
	   "decl %1\n\t"	// Ƿָ1 ָesi ָʱĸַ
	   "cmpb $0,(%1)\n\t"	// ַNULL ַ
	   "je 7f\n\t"		// ǣת7 
	   "movl %1,%0\n"	// ַָesi ebx
	   "3:\tlodsb\n\t"	// ȡ1 һַds:[esi]??alesi++
	   "testb %%al,%%al\n\t"	// ַNULL ַ
	   "je 5f\n\t"		// ǣʾ1 ת5
	   "movl %4,%%edi\n\t"	// edi ٴָ2 ס
	   "movl %%edx,%%ecx\n\t"	// 2 ֵecx
	   "repne\n\t"		// al д1 ַ봮2 ÿַȽϣ
	   "scasb\n\t"		// al ַǷǷָ
	   "jne 3b\n\t"		// Ƿָת3⴮1 һַ
	   "decl %1\n\t"	// Ƿָesi--ָ÷ַָ
	   "cmpb $0,(%1)\n\t"	// ÷ָNULL ַ
	   "je 5f\n\t"		// ǣת5
	   "movb $0,(%1)\n\t"	// ǣ򽫸÷ָNULL ַ滻
	   "incl %1\n\t"	// esi ָ1 һַҲʣമס
	   "jmp 6f\n"		// ת6 
	   "5:\txorl %1,%1\n"	// esi 㡣
	   "6:\tcmpb $0,(%0)\n\t"	// ebx ָָNULL ַ
	   "jne 7f\n\t"		// ǣת7
	   "xorl %0,%0\n"	// ǣebx=NULL
	   "7:\ttestl %0,%0\n\t"	// ebx ָΪNULL 
	   "jne 8f\n\t"		// ת8롣
	   "movl %0,%1\n"	// esi ΪNULL
"8:": "=b" (__res), "=S" (___strtok): "" (___strtok), "1" (s), "g" (ct):"ax", "cx", "dx",
	   "di");
  return __res;			// ָtoken ָ롣
}

//// ڴ鸴ơԴַsrc ʼn ֽڵĿĵַdest 
// dest - ƵĿĵַsrc - ƵԴַn - ֽ
// %0 - ecx(n)%1 - esi(src)%2 - edi(dest)
extern inline void *
memcpy (void *dest, const void *src, int n)
{
  __asm__ ("cld\n\t"		// 巽λ
	   "rep\n\t"		// ظִиecx ֽڣ
	   "movsb"		// ds:[esi]es:[edi]esi++edi++
::"c" (n), "S" (src), "D" (dest):"cx", "si", "di");
  return dest;			// Ŀĵַ
}

//// ڴƶͬڴ鸴ƣƶķ
// dest - ƵĿĵַsrc - ƵԴַn - ֽ
// dest<src %0 - ecx(n)%1 - esi(src)%2 - edi(dest)
// %0 - ecx(n)%1 - esi(src+n-1)%2 - edi(dest+n-1)
// Ϊ˷ֹڸʱصǡ
extern inline void *
memmove (void *dest, const void *src, int n)
{
  if (dest < src)
    __asm__ ("cld\n\t"		// 巽λ
	     "rep\n\t"		// ds:[esi]es:[edi]esi++edi++
	     "movsb"		// ظִиecx ֽڡ
  ::"c" (n), "S" (src), "D" (dest):"cx", "si", "di");
  else
    __asm__ ("std\n\t"		// ÷λĩ˿ʼơ
	     "rep\n\t"		// ds:[esi]es:[edi]esi--edi--
	     "movsb"		// ecx ֽڡ
  ::"c" (n), "S" (src + n - 1), "D" (dest + n - 1):"cx", "si",
	     "di");
  return dest;
}

//// Ƚn ֽڵڴ棨ַʹNULL ֽҲֹͣȽϡ
// cs - ڴ1 ַct - ڴ2 ַcount - Ƚϵֽ
// %0 - eax(__res)%1 - eax(0)%2 - edi(ڴ1)%3 - esi(ڴ2)%4 - ecx(count)
// أ1>2 11<2-11==2򷵻0
extern inline int
memcmp (const void *cs, const void *ct, int count)
{
  register int __res __asm__ ("ax");	// __res ǼĴ
  __asm__ ("cld\n\t"		// 巽λ
	   "repe\n\t"		// ظ
	   "cmpsb\n\t"		// Ƚds:[esi]es:[edi]ݣesi++edi++
	   "je 1f\n\t"		// ͬת10(eax)ֵ
	   "movl $1,%%eax\n\t"	// eax 1
	   "jl 1f\n\t"		// ڴ2 ݵֵ<ڴ1ת1
	   "negl %%eax\n"	// eax = -eax
"1:": "=a" (__res): "" (0), "D" (cs), "S" (ct), "c" (count):"si", "di",
	   "cx");
  return __res;			// رȽϽ
}

//// n ֽڴСڴ(ַ)Ѱַָ
// cs - ָڴַc - ַָcount - ڴ鳤ȡ
// %0 - edi(__res)%1 - eax(ַc)%2 - edi(ڴַcs)%3 - ecx(ֽcount)
// صһƥַָ룬ûҵ򷵻NULL ַ
extern inline void *
memchr (const void *cs, char c, int count)
{
  register void *__res __asm__ ("di");	// __res ǼĴ
  if (!count)			// ڴ鳤==0򷵻NULLûҵ
    return NULL;
  __asm__ ("cld\n\t"		// 巽λ
	   "repne\n\t"		// ظִ䣬
	   "scasb\n\t"		// al ַes:[edi]ַȽϣedi++
	   "je 1f\n\t"		// ǰת1 
	   "movl $1,%0\n"	// edi 1
	   "1:\tdecl %0"	// edi ָҵַNULL
: "=D" (__res): "a" (c), "D" (cs), "c" (count):"cx");
  return __res;			// ַָ롣
}

//// ַдָڴ顣
// ַc дs ָڴ򣬹count ֽڡ
// %0 - eax(ַc)%1 - edi(ڴַ)%2 - ecx(ֽcount)
extern inline void *
memset (void *s, char c, int count)
{
  __asm__ ("cld\n\t"		// 巽λ
	   "rep\n\t"		// ظecx ָĴִ
	   "stosb"		// al ַes:[edi]Уedi++
::"a" (c), "D" (s), "c" (count):"cx", "di");
  return s;
}

#endif
