www.pudn.com > linux011.rar > string.h


#ifndef _STRING_H_
#define _STRING_H_
/* 
  其实vc编译器本身包含了这些函数定义,我们完全可以把string.h内的函数定义 
  都注释掉,然后为每个.c文件编译时加上/Ox编译选项即可。 
*/ 

#ifndef NULL
#define NULL 0
#endif

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

extern char *strerror (int errno);
/*
* 这个字符串头文件以内嵌函数的形式定义了所有字符串操作函数。使用gcc 时,同时
* 假定了ds=es=数据空间,这应该是常规的。绝大多数字符串函数都是经手工进行大量
* 优化的,尤其是函数strtok、strstr、str[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{ 
		pushf 
		mov esi,src 
		mov edi,dest 
		cld		// 清方向位。 
	l1:	lodsb	// 加载DS:[esi]处1 字节->al,并更新esi。 
		stosb		// 存储字节al->ES:[edi],并更新edi。 
		test al,al	// 刚存储的字节是0? 
		jne l1	// 不是则跳转到标号l1 处,否则结束。 
		popf 
	} 
	return dest;			// 返回目的字符串指针。
}
/*extern _inline char * 
strcpy (char *dest, const char *src) 
{ 
  __asm__ ("cld\n"		// 清方向位。 
	   "1:\tlodsb\n\t"	// 加载DS:[esi]处1 字节??al,并更新esi。 
	   "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)。
static _inline char *
strncpy (char *dest, const char *src, int count)
{
	_asm{ 
		pushf 
		mov esi,src 
		mov edi,dest 
		mov ecx,count 
		cld		// 清方向位。 
	l1:	dec ecx	// 寄存器ecx--(count--)。 
		js l2		// 如果count<0 则向前跳转到标号l2,结束。 
		lodsb		// 取ds:[esi]处1 字节->al,并且esi++。 
		stosb		// 存储该字节->es:[edi],并且edi++。 
		test al,al	// 该字节是0? 
		jne l1		// 不是,则向前跳转到标号l1 处继续拷贝。 
		rep stosb		// 否则,在目的串中存放剩余个数的空字符。 
	l2:	popf 
	}
	return dest;			// 返回目的字符串指针。
}
/*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 字节??al,并且esi++。 
	   "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 { 
		pushf 
		mov esi,src 
		mov edi,dest 
		xor al,al 
		mov ecx,0xffffffff 
		cld		// 清方向位。 
		repne scasb		// 比较al 与es:[edi]字节,并更新edi++, 
						// 直到找到目的串中是0 的字节,此时edi 已经指向后1 字节。 
		dec edi		// 让es:[edi]指向0 值字节。 
	l1: lodsb	// 取源字符串字节ds:[esi]->al,并esi++。 
		stosb		// 将该字节存到es:[edi],并edi++。 
		test al,al	// 该字节是0? 
		jne l1	// 不是,则向后跳转到标号1 处继续拷贝,否则结束。 
		popf 
	}
	return dest;			// 返回目的字符串指针。
}
/*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]??al,并esi++。 
	   "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)。
static _inline char *
strncat (char *dest, const char *src, int count)
{
	_asm { 
		pushf 
		mov esi,src 
		mov edi,dest 
		xor al,al 
		mov ecx,0xffffffff 
		cld		// 清方向位。 
		repne scasb		// 比较al 与es:[edi]字节,edi++。直到找到目的串的末端0 值字节。 
		dec edi	// edi 指向该0 值字节。 
		mov ecx,count	// 欲复制字节数??ecx。 
	l1: dec ecx	// ecx--(从0 开始计数)。 
		js l2		// ecx <0 ?,是则向前跳转到标号l2 处。 
		lodsb		// 否则取ds:[esi]处的字节->al,esi++。 
		stosb		// 存储到es:[edi]处,edi++。 
		test al,al	// 该字节值为0? 
		jne l1		// 不是则向后跳转到标号1 处,继续复制。 
	l2: xor al,al	// 将al 清零。 
		stosb		// 存到es:[edi]处。 
		popf 
	}
  return dest;			// 返回目的字符串指针。
}
/*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]处的字节??al,esi++。 
	   "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;			// 返回目的字符串指针。 
}*/ 

//// 将一个字符串与另一个字符串进行比较。
// 参数:csrc - 字符串1,ct - 字符串2。
// %0 - eax(__res)返回值,%1 - edi(csrc)字符串1 指针,%2 - esi(ct)字符串2 指针。
// 返回:如果串1 > 串2,则返回1;串1 = 串2,则返回0;串1 < 串2,则返回-1。
extern _inline int
strcmp (const char *csrc, const char *ct)
{
//  register int __res;	// __res 是寄存器变量(eax)。
  _asm{ 
	  pushf 
	  mov edi,csrc 
	  mov esi,ct 
	  cld		// 清方向位。 
  l1: lodsb	// 取字符串2 的字节ds:[esi]??al,并且esi++。 
	  scasb		// al 与字符串1 的字节es:[edi]作比较,并且edi++。 
	  jne l2		// 如果不相等,则向前跳转到标号2。 
	  test al,al	// 该字节是0 值字节吗(字符串结尾)? 
	  jne l1		// 不是,则向后跳转到标号1,继续比较。 
	  xor eax,eax	// 是,则返回值eax 清零, 
	  jmp l3		// 向前跳转到标号3,结束。 
  l2: mov eax,1	// eax 中置1。 
	  jl l3		// 若前面比较中串2 字符<串1 字符,则返回正值,结束。 
	  neg eax	// 否则eax = -eax,返回负值,结束。 
//  l3: mov __res,eax 
  l3: popf 
  }
//  return __res;			// 返回比较结果。
}
/*extern _inline int 
strcmp (const char *csrc, const char *ct) 
{ 
  register int __res __asm__ ("ax");	// __res 是寄存器变量(eax)。 
  __asm__ ("cld\n"		// 清方向位。 
	   "1:\tlodsb\n\t"	// 取字符串2 的字节ds:[esi]??al,并且esi++。 
	   "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" (csrc), "S" (ct):"si", "di"); 
  return __res;			// 返回比较结果。 
}*/ 

//// 字符串1 与字符串2 的前count 个字符进行比较。
// 参数:csrc - 字符串1,ct - 字符串2,count - 比较的字符数。
// %0 - eax(__res)返回值,%1 - edi(csrc)串1 指针,%2 - esi(ct)串2 指针,%3 - ecx(count)。
// 返回:如果串1 > 串2,则返回1;串1 = 串2,则返回0;串1 < 串2,则返回-1。
static _inline int
strncmp (const char *csrc, const char *ct, int count)
{
//  register int __res;	// __res 是寄存器变量(eax)。 
  _asm{ 
	  pushf 
      mov edi,csrc 
	  mov esi,ct 
	  mov ecx,count 
	  cld		// 清方向位。 
  l1: dec ecx	// count--。 
	  js l2		// 如果count<0,则向前跳转到标号2。 
	  lodsb		// 取串2 的字符ds:[esi]??al,并且esi++。 
	  scasb		// 比较al 与串1 的字符es:[edi],并且edi++。 
	  jne l3		// 如果不相等,则向前跳转到标号3。 
	  test al,al	// 该字符是NULL 字符吗? 
	  jne l1		// 不是,则向后跳转到标号1,继续比较。 
  l2: xor eax,eax	// 是NULL 字符,则eax 清零(返回值)。 
	  jmp l4		// 向前跳转到标号4,结束。 
  l3: mov eax,1	// eax 中置1。 
	  jl l4		// 如果前面比较中串2 字符<串2 字符,则返回1,结束。 
	  neg eax	// 否则eax = -eax,返回负值,结束。 
//  l4: mov __res,eax 
  l4: popf 
  }
//  return __res;			// 返回比较结果。
}
/*extern _inline int 
strncmp (const char *csrc, 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]??al,并且esi++。 
	   "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" (csrc), "S" (ct), "c" (count):"si", "di", 
	   "cx"); 
  return __res;			// 返回比较结果。 
}*/ 

//// 在字符串中寻找第一个匹配的字符。
// 参数:s - 字符串,c - 欲寻找的字符。
// %0 - eax(__res),%1 - esi(字符串指针s),%2 - eax(字符c)。
// 返回:返回字符串中第一次出现匹配字符的指针。若没有找到匹配的字符,则返回空指针。
static _inline char *
strchr (const char *s, char c)
{
//  register char *__res;	// __res 是寄存器变量(eax)。 
  _asm{ 
	  pushf 
	  mov esi,s 
	  mov ah,c 
	  cld		// 清方向位。 
  l1: lodsb	// 取字符串中字符ds:[esi]->al,并且esi++。 
	  cmp al,ah	// 字符串中字符al 与指定字符ah 相比较。 
	  je l2		// 若相等,则向前跳转到标号2 处。 
	  test al,al	// al 中字符是NULL 字符吗?(字符串结尾?) 
	  jne l1		// 若不是,则向后跳转到标号1,继续比较。 
	  mov esi,1	// 是,则说明没有找到匹配字符,esi 置1。 
  l2: mov eax,esi	// 将指向匹配字符后一个字节处的指针值放入eax 
	  dec eax		// 将指针调整为指向匹配的字符。 
//	  mov __res,eax 
	  popf 
  }
//  return __res;			// 返回指针。
}
/*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]??al,并且esi++。 
	   "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)。
// 返回:返回字符串中最后一次出现匹配字符的指针。若没有找到匹配的字符,则返回空指针。
static _inline char *
strrchr (const char *s, char c)
{
//  register char *__res;	// __res 是寄存器变量(edx)。 
  _asm{ 
	  pushf 
	  xor edx,edx 
	  mov esi,s 
	  mov ah,c 
	  cld		// 清方向位。 
  l1: lodsb	// 取字符串中字符ds:[esi]->al,并且esi++。 
	  cmp al,ah	// 字符串中字符al 与指定字符ah 作比较。 
	  jne l2		// 若不相等,则向前跳转到标号2 处。 
	  mov edx,esi	// 将字符指针保存到edx 中。 
	  dec edx		// 指针后退一位,指向字符串中匹配字符处。 
  l2: test al,al	// 比较的字符是0 吗(到字符串尾)? 
	  jne l1	// 不是则向后跳转到标号1 处,继续比较。 
//	  mov __res,edx 
      mov eax,edx 
	  popf 
  }
//  return __res;			// 返回指针。
}
/*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]??al,并且esi++。 
	   "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 中。
// 参数:csrc - 字符串1 指针,ct - 字符串2 指针。
// %0 - esi(__res),%1 - eax(0),%2 - ecx(-1),%3 - esi(串1 指针csrc),%4 - (串2 指针ct)。
// 返回字符串1 中包含字符串2 中任何字符的首个字符序列的长度值。
extern _inline int
strspn (const char *csrc, const char *ct)
{
  register char *__res;	// __res 是寄存器变量(esi)。 
  _asm{ 
	  pushf 
	  xor al,al 
	  mov ebx,ct 
	  mov edi,ebx	// 首先计算串2 的长度。串2 指针放入edi 中。 
	  mov ecx,0xffffffff 
	  cld		// 清方向位。 
	  repne scasb// 比较al(0)与串2 中的字符(es:[edi]),并edi++。如果不相等就继续比较(ecx 逐步递减)。 
	  not ecx	// ecx 中每位取反。 
	  dec ecx	// ecx--,得串2 的长度值。-> ecx 
	  mov edx,ecx	// 将串2 的长度值暂放入edx 中。 
	  mov esi,csrc 
  l1: lodsb	// 取串1 字符ds:[esi]->al,并且esi++。 
	  test al,al	// 该字符等于0 值吗(串1 结尾)? 
	  je l2		// 如果是,则向前跳转到标号2 处。 
	  mov edi,ebx	// 取串2 头指针放入edi 中。 
	  mov ecx,edx	// 再将串2 的长度值放入ecx 中。 
	  repne scasb	// 比较al 与串2 中字符es:[edi],并且edi++。如果不相等就继续比较。 
	  je l1		// 如果相等,则向后跳转到标号1 处。 
  l2: dec esi	// esi--,指向最后一个包含在串2 中的字符。 
	  mov __res,esi 
	  popf 
  }
  return __res - csrc;		// 返回字符序列的长度值。
}
/*extern _inline int 
strspn (const char *csrc, 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]??al,并且esi++。 
	   "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), "" (csrc), "g" (ct):"ax", "cx", "dx", 
	   "di"); 
  return __res - csrc;		// 返回字符序列的长度值。 
}*/ 

//// 寻找字符串1 中不包含字符串2 中任何字符的首个字符序列。
// 参数:csrc - 字符串1 指针,ct - 字符串2 指针。
// %0 - esi(__res),%1 - eax(0),%2 - ecx(-1),%3 - esi(串1 指针csrc),%4 - (串2 指针ct)。
// 返回字符串1 中不包含字符串2 中任何字符的首个字符序列的长度值。
extern _inline int
strcsrcpn (const char *csrc, const char *ct)
{
  register char *__res;	// __res 是寄存器变量(esi)。 
	_asm{ 
		pushf 
		xor al,al 
		mov ecx,0xffffffff 
		mov ebx,ct 
		mov edi,ebx	// 首先计算串2 的长度。串2 指针放入edi 中。 
		cld		// 清方向位。 
		repne scasb// 比较al(0)与串2 中的字符(es:[edi]),并edi++。如果不相等就继续比较(ecx 逐步递减)。 
		not ecx	// ecx 中每位取反。 
		dec ecx	// ecx--,得串2 的长度值。 
		mov edx,ecx	// 将串2 的长度值暂放入edx 中。 
		mov esi,csrc 
	l1: lodsb	// 取串1 字符ds:[esi]->al,并且esi++。 
		test al,al	// 该字符等于0 值吗(串1 结尾)? 
		je l2		// 如果是,则向前跳转到标号2 处。 
		mov edi,ebx	// 取串2 头指针放入edi 中。 
		mov ecx,edx 	// 再将串2 的长度值放入ecx 中。 
		repne scasb	// 比较al 与串2 中字符es:[edi],并且edi++。如果不相等就继续比较。 
		jne l1		// 如果不相等,则向后跳转到标号1 处。 
	l2: dec esi 
		mov __res,esi	// esi--,指向最后一个包含在串2 中的字符。 
		popf 
	}
  return __res - csrc;		// 返回字符序列的长度值。
}
/*extern _inline int 
strcsrcpn (const char *csrc, 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]??al,并且esi++。 
	   "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), "" (csrc), "g" (ct):"ax", "cx", "dx", 
	   "di"); 
  return __res - csrc;		// 返回字符序列的长度值。 
}*/ 

//// 在字符串1 中寻找首个包含在字符串2 中的任何字符。
// 参数:csrc - 字符串1 的指针,ct - 字符串2 的指针。
// %0 -esi(__res),%1 -eax(0),%2 -ecx(0xffffffff),%3 -esi(串1 指针csrc),%4 -(串2 指针ct)。
// 返回字符串1 中首个包含字符串2 中字符的指针。
extern _inline char *
strpbrk (const char *csrc, const char *ct)
{
//  register char *__res;	// __res 是寄存器变量(esi)。 
	_asm{ 
		pushf 
		xor al,al 
		mov ebx,ct 
		mov edi,ebx	// 首先计算串2 的长度。串2 指针放入edi 中。 
		mov ecx,0xffffffff 
		cld		// 清方向位。 
		repne scasb// 比较al(0)与串2 中的字符(es:[edi]),并edi++。如果不相等就继续比较(ecx 逐步递减)。 
		not ecx	// ecx 中每位取反。 
		dec ecx	// ecx--,得串2 的长度值。 
		mov edx,ecx	// 将串2 的长度值暂放入edx 中。 
		mov esi,csrc 
	l1: lodsb	// 取串1 字符ds:[esi]??al,并且esi++。 
		test al,al	// 该字符等于0 值吗(串1 结尾)? 
		je l2		// 如果是,则向前跳转到标号2 处。 
		mov edi,ebx	// 取串2 头指针放入edi 中。 
		mov ecx,edx	// 再将串2 的长度值放入ecx 中。 
		repne scasb		// 比较al 与串2 中字符es:[edi],并且edi++。如果不相等就继续比较。 
		jne l1	// 如果不相等,则向后跳转到标号1 处。 
		dec esi	// esi--,指向一个包含在串2 中的字符。 
		jmp l3		// 向前跳转到标号3 处。 
	l2: xor esi,esi	// 没有找到符合条件的,将返回值为NULL。 
//	l3: mov __res,esi 
	l3: mov eax,esi 
		popf 
	}
//  return __res;			// 返回指针值。
}
/*extern _inline char * 
strpbrk (const char *csrc, 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]??al,并且esi++。 
	   "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), "" (csrc), "g" (ct):"ax", "cx", "dx", 
	   "di"); 
  return __res;			// 返回指针值。 
}*/ 

//// 在字符串1 中寻找首个匹配整个字符串2 的字符串。
// 参数:csrc - 字符串1 的指针,ct - 字符串2 的指针。
// %0 -eax(__res),%1 -eax(0),%2 -ecx(0xffffffff),%3 -esi(串1 指针csrc),%4 -(串2 指针ct)。
// 返回:返回字符串1 中首个匹配字符串2 的字符串指针。
extern _inline char *
strstr (const char *csrc, const char *ct)
{
//  register char *__res;	// __res 是寄存器变量(eax)。 
	_asm { 
		pushf 
		mov ebx,ct 
		mov edi,ebx	// 首先计算串2 的长度。串2 指针放入edi 中。 
		mov ecx,0xffffffff 
		xor al,al	// al = 0 
		cld 		// 清方向位。 
		repne scasb// 比较al(0)与串2 中的字符(es:[edi]),并edi++。如果不相等就继续比较(ecx 逐步递减)。 
		not ecx	// ecx 中每位取反。 
		dec ecx 
// 注意!如果搜索串为空,将设置Z 标志 // 得串2 的长度值。 
		mov edx,ecx	// 将串2 的长度值暂放入edx 中。 
		mov esi,csrc 
	l1: mov edi,ebx	// 取串2 头指针放入edi 中。 
		mov ecx,edx	// 再将串2 的长度值放入ecx 中。 
		mov eax,esi	// 将串1 的指针复制到eax 中。 
		repe cmpsb// 比较串1 和串2 字符(ds:[esi],es:[edi]),esi++,edi++。若对应字符相等就一直比较下去。 
		je l2 
// 对空串同样有效,见上面 // 若全相等,则转到标号2。 
		xchg esi,eax	// 串1 头指针->esi,比较结果的串1 指针->eax。 
		inc esi	// 串1 头指针指向下一个字符。 
		cmp [eax-1],0	// 串1 指针(eax-1)所指字节是0 吗? 
		jne l1	// 不是则跳转到标号1,继续从串1 的第2 个字符开始比较。 
		xor eax,eax	// 清eax,表示没有找到匹配。 
//	l2: mov __res,eax 
	l2:	popf 
	}
//  return __res;			// 返回比较结果。
}
/*extern _inline char * 
strstr (const char *csrc, 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" (csrc), "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;	// __res 是寄存器变量(ecx)。 
	_asm{ 
		pushf 
		mov edi,s 
		mov ecx,0xffffffff 
		xor al,al 
		cld		// 清方向位。 
		repne scasb		// al(0)与字符串中字符es:[edi]比较,若不相等就一直比较。 
		not ecx	// ecx 取反。 
		dec ecx		// ecx--,得字符串得长度值。 
//		mov __res,ecx 
		mov eax,ecx 
		popf 
	}
//  return __res;			// 返回字符串长度值。
}
/*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 - 待处理的字符串1,ct - 包含各个分割符的字符串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, register const char *ct)
{
//  register char *__res; 
	_asm { 
		pushf 
		mov esi,s 
		test esi,esi	// 首先测试esi(字符串1 指针s)是否是NULL。 
		jne l1		// 如果不是,则表明是首次调用本函数,跳转标号1。 
		mov ebx,strtok 
		test ebx,ebx	// 如果是NULL,则表示此次是后续调用,测ebx(__strtok)。 
		je l8		// 如果ebx 指针是NULL,则不能处理,跳转结束。 
		mov esi,ebx	// 将ebx 指针复制到esi。 
	l1: xor ebx,ebx	// 清ebx 指针。 
		mov edi,ct	// 下面求字符串2 的长度。edi 指向字符串2。 
		mov ecx,0xffffffff 	// 置ecx = 0xffffffff。 
		xor eax,eax	// 清零eax。 
		cld 
		repne scasb// 将al(0)与es:[edi]比较,并且edi++。直到找到字符串2 的结束null 字符,或计数ecx==0。 
		not ecx	// 将ecx 取反, 
		dec ecx	// ecx--,得到字符串2 的长度值。 
		je l7	// 分割符字符串空 // 若串2 长度为0,则转标号7。 
		mov edx,ecx	// 将串2 长度暂存入edx。 
	l2: lodsb	// 取串1 的字符ds:[esi]->al,并且esi++。 
		test al,al	// 该字符为0 值吗(串1 结束)? 
		je l7		// 如果是,则跳转标号7。 
		mov edi,ct	// edi 再次指向串2 首。 
		mov ecx,edx	// 取串2 的长度值置入计数器ecx。 
		repne scasb// 将al 中串1 的字符与串2 中所有字符比较,判断该字符是否为分割符。 
		je l2		// 若能在串2 中找到相同字符(分割符),则跳转标号2。 
		dec esi	// 若不是分割符,则串1 指针esi 指向此时的该字符。 
		cmp [esi],0	// 该字符是NULL 字符吗? 
		je l7		// 若是,则跳转标号7 处。 
		mov ebx,esi	// 将该字符的指针esi 存放在ebx。 
	l3: lodsb	// 取串1 下一个字符ds:[esi]->al,并且esi++。 
		test al,al	// 该字符是NULL 字符吗? 
		je l5		// 若是,表示串1 结束,跳转到标号5。 
		mov edi,ct	// edi 再次指向串2 首。 
		mov ecx,edx	// 串2 长度值置入计数器ecx。 
		repne scasb // 将al 中串1 的字符与串2 中每个字符比较,测试al 字符是否是分割符。 
		jne l3		// 若不是分割符则跳转标号3,检测串1 中下一个字符。 
		dec esi	// 若是分割符,则esi--,指向该分割符字符。 
		cmp [esi],0	// 该分割符是NULL 字符吗? 
		je l5		// 若是,则跳转到标号5。 
		mov [esi],0	// 若不是,则将该分割符用NULL 字符替换掉。 
		inc esi	// esi 指向串1 中下一个字符,也即剩余串首。 
		jmp l6		// 跳转标号6 处。 
	l5: xor esi,esi	// esi 清零。 
	l6: cmp [ebx],0	// ebx 指针指向NULL 字符吗? 
		jne l7	// 若不是,则跳转标号7。 
		xor ebx,ebx	// 若是,则让ebx=NULL。 
	l7: test ebx,ebx	// ebx 指针为NULL 吗? 
		jne l8	// 若不是则跳转8,结束汇编代码。 
		mov esi,ebx	// 将esi 置为NULL。 
//	l8: mov __res,esi 
	l8: mov eax,esi 
		popf 
	}
//  return __res;			// 返回指向新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]??al,并且esi++。 
	   "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]??al,并且esi++。 
	   "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{ 
		pushf 
		mov esi,src 
		mov edi,dest 
		mov ecx,n 
		cld		// 清方向位。 
		rep movsb	// 重复执行复制ecx 个字节,从ds:[esi]到es:[edi],esi++,edi++。 
		popf 
	}
	return 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块2 返回1;块1<块2,返回-1;块1==块2,则返回0。
extern _inline int
memcmp (const void *csrc, const void *ct, int count)
{
//  register int __res; //__asm__ ("ax")	 __res 是寄存器变量。 
	_asm { 
		pushf 
		mov edi,csrc 
		mov esi,ct 
		xor eax,eax // eax = 0 
		mov ecx,count 
		cld		// 清方向位。 
		repe cmpsb// 比较ds:[esi]与es:[edi]的内容,并且esi++,edi++。如果相等则重复, 
		je l1		// 如果都相同,则跳转到标号1,返回0(eax)值 
		mov eax,1	// 否则eax 置1, 
		jl l1		// 若内存块2 内容的值<内存块1,则跳转标号1。 
		neg eax	// 否则eax = -eax。 
//	l1: mov __res,eax 
	l1:	popf 
	}
//  return __res;			// 返回比较结果。
}
/*extern _inline int 
memcmp (const void *csrc, 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"		// 如果都相同,则跳转到标号1,返回0(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" (csrc), "S" (ct), "c" (count):"si", "di", 
	   "cx"); 
  return __res;			// 返回比较结果。 
}*/ 

//// 在n 字节大小的内存块(字符串)中寻找指定字符。
// 参数:csrc - 指定内存块地址,c - 指定的字符,count - 内存块长度。
// %0 - edi(__res),%1 - eax(字符c),%2 - edi(内存块地址csrc),%3 - ecx(字节数count)。
// 返回第一个匹配字符的指针,如果没有找到,则返回NULL 字符。
extern _inline void *
memchr (const void *csrc, char c, int count)
{
//  register void *__res;	// __res 是寄存器变量。
  if (!count)			// 如果内存块长度==0,则返回NULL,没有找到。
    return NULL; 
	_asm { 
		pushf 
		mov edi,csrc 
		mov ecx,count 
		mov al,c 
		cld		// 清方向位。 
		repne scasb// al 中字符与es:[edi]字符作比较,并且edi++,如果不相等则重复执行下面语句, 
		je l1		// 如果相等则向前跳转到标号1 处。 
		mov edi,1	// 否则edi 中置1。 
	l1: dec edi	// 让edi 指向找到的字符(或是NULL)。 
//		mov __res,edi 
		mov eax,edi 
		popf 
	}
//  return __res;			// 返回字符指针。
}
/*extern _inline void * 
memchr (const void *csrc, 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" (csrc), "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 { 
		pushf 
		mov edi,s 
		mov ecx,count 
		mov al,c 
		cld		// 清方向位。 
		rep stosb// 将al 中字符存入es:[edi]中,并且edi++。重复ecx 指定的次数,执行 
		popf 
	}
  return s;
}
/*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