⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 string.h

📁 linux0.11的vc下的源代码 注释很详细
💻 H
📖 第 1 页 / 共 3 页
字号:
#ifndef _STRING_H_#define _STRING_H_/*
  其实vc编译器本身包含了这些函数定义,我们完全可以把string.h内的函数定义
  都注释掉,然后为每个.c文件编译时加上/Ox编译选项即可。
*/
#ifndef NULL#define NULL 0#endif#ifndef _SIZE_T#define _SIZE_Ttypedef unsigned int size_t;#endifextern 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 intstrcmp (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 intstrncmp (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。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -