linux-011之string.h头文件

#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);
/*
*这个字符串头文件以内嵌函数的形式定义来所有字符串操作函数.使用gcc时,同时假定了ds=es=数据
*空间,这应该是常规的.大部分的字符串功能函数都是手工进行优化的,尤其是strtok,strstr,str[c]
*他们应该可以工作,但是不那么容易理解,所有的函数都是使用寄存器直接操作的,使得所有的功能都很
*快并且整洁.
*/

/*
*将一个字符串(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字节->al,并更新esi
		"stosb\n\t"           //存储字节al->ES:[edi],并更新edi
		"testb %%al,%%al\n\t" //刚存储字节是不是0
		"jne 1b"              //不是0向后跳转1处,否则结束
		:
		:"S"(src),"D"(dest)
		:"si","di","ax"
		);		
	return dest;
}

/*
*拷贝源字符串count个字节到目的字符串,如果源串长度小于count,就附加空字符到目的字符串
*参数:dest-目的字符串指针,src-源字符串指针,count-拷贝字节数
*%0-esi(src),%1-edi(dest),%2-ecx(count)
*/
extern inline char* strncpy(char * dest,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],->al,esi++
		"stosb\n\t"         //存储字节al->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(sec),%1-edi(dest),%2-eax(0),%3-ecx(0xffffffff)
*/
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"   //额昂edi指向0值字节
		"1:\t lodsb\n\t"//取源字符串ds:[esi]->al,esi++
		"stosb\n\t"      //存储al->ds:[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(0xffffffff),%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--
		"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清0
		"stosb"              //存储到es:[edi]处
		:
		:"S"(src),"D"(dest),"a"(0),"c"(0xffffffff),"g"(count)
		:"si","di","ax","cx"
		);	
	return dest;
}

/*
*将以一个字符串和另一个字符串比较
*参数:cs-源字符串指针,ct-目的字符串指针
*%0-eax(_res),%1-edi(cs),%2-esi(ct)
*返回:串1>串2 返回1;串1=串2,返回0,串1<串2,返回-1
*/
extern inline int strcmp(const char* cs,cosnt chat* ct)
{
	register int __asm__("ax");    //寄存器变量	
	__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"	       //不是0,跳转到标号1,继续比较
		"xorl %%eax,%%eax\n\t" //是0,返回值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-字符串1,st-字符串2,count比较的字节数
*%0-eax(_res),%1-edi(cs),%2-esi(ct),%3-ecx(count)
*返回:串1 > 串2,则返回1,串1 = 串2,则返回0,串1< 串2,则返回-1
*/
extern inlint int strncmp(const char*cs,cosnt char*st,int count)
{
	register _res __asm__("ax");       //寄存器变量
	__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"		   //不是NULL,则跳转到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<串1,返回1
		"negl %%eax\n"		   //否则返回-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");//寄存器变量
	__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"		  //是,则说明没有找到
		"2:\t movl %1,%0\n\t"	  //将指向匹配字符后一个字节的指针->eax
		"decl %0"		  //eax--
		:"=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]->al,esi++
		"cmpb %%ah,%%al\n\t"	  //字符串中字符al与指定字符ah比较
		"jne 2f\n\t"		  // 不相等,跳转到2处
		"movl %%esi,%0\n\t"	  // 将字符指针保存到edx中
		"decl %0\n"		  // 指针减1,指向匹配字符处
		"2:\ttestb %%al,%%al\n\t" // 比较的字符是0吗(字符串末尾)
		"jne 1b"		  // 不是就跳转到1处,继续比较
		:"d="(_res)
		:""(0),"S"(s),"a"(c)
		:"ax","di"
		);	
	return _res;
}

/*
*在字符串1中寻找第一个字符序列,该字符序列中任何字符都包含在字符串2中
*参数:cs-字符串1指针,ct字符串2指针
*%0-esi(res),%1-eax(0),%2-ecx(0xffffffff),%3-ecx(cs),%4-(ct)
*/
extern inline int strspn(cosnt 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]->al,esi++
		"testb %%al,%%al\n\t"	   //该字符等于0值吗(串1结尾)
		"je 2f\n\t"		   //如果是,跳转到2处
		"movl %4,%%edi\n\t"	   //取串2指针放入edi中
		"movl %%edi,%%ecx\n\t"	   //在将串2长度放入ecx中
		"repne \n\t"		   // 在比较al与串2中字符es:[edi],edi++
		"scasb \n\t"		   //不等就继续比较
		"je 1b\n"		   // 相等就跳转到1处
		"2:\tdecl %0"              //edi--指向最后一个包含在串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-ecx(cs),%4-(ct)
*返回:返回字符串1中不包含字符串2中任何字符的首个字符序列的长度值
*/
extern inline int strcspn(cosnt char*s,cosnt 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])
		"scasb\n\t"		    //不等就继续比较
		"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头指针放入ecx中
		"movl %%edx,%%ecx\n\t"	    //再将串2的长度值放入ecx中
		"repne \n\t"		    //比较al与串2中字符es:[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指针,st-字符串2指针
*%0-esi(res),%1-eax(0),%2-ecx(0xffffffff),%3-ecx(cs),%4-(ct)
*返回字符串1中首个包含字符串2中字符的指针
*/
extern inline char* strbrk(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])
		"scasb \n\t"		  //如果不等就继续比较
		"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,
		"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]
		"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-,ct-
*%0-eax(res),%1-eax(0),%2-ecx(0xffffffff),%3-esi(cs),%4-(ct)
*返回:返回字符串1中首个匹配字符串2的字符串的指针
*/
extern inline char* strstr(const char*cs cosnt char*ct)
{
	register char* __res __asm__("ax");//res是寄存器变量
	__asm__("cld\n\t"		   //
		"movl %4,%%edi\n\t"	   //首先计算串2的长度,串2指针放入edi中
		"repne\n\t"		   //比较al(0)与串2的字符es:[edi]
		"scasb\n\t"		   //不等就继续比较
		"notl %%ecx\n\t"	   //ecx每位取反
		"decl %%ecx\n\t"	   //ecx--,得到串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]
		"cmpsb\n\t"		   //若对应字符相等就一直比较下去
		"je 2f\n\t"		   //全等就跳转到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的第二个字符比较
		"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是寄存器变量
	__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;

/*
*利用字符串2中的字符串将字符串1分别分割成标记序列
*将串1看作是包含零个或多个单词的序列,并有分割符字符串2中的一个或多个字符分开
*第一次调用strtok时,将返回指向字符串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中第一个token,如果没有找到token,则返回一个null指针
*后续使用字符串s指针为null的调用,将在原字符串s中搜索下一个token
*/
extern inline char* strtok(char*s,const char*ct)
{
		register char* __res __asm__("si");//_res是寄存器值
		__asm__("testl %1,%1\n\t"          //首先esi(字符串1指针s)是否为null
						"jne 1f"                   //如果不是,则表明是首次调用本函数,跳到1
						"test1 %0,%0\n\t"          //如果是NULL,则表示此次是后续处理,测ebx(_strtok)
						"je 8f\n\t"                //如果ebx指针式NULL,则不能处理,跳转结束
						"movl %0,%1\n"             //
						"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 %%ecs\n\t"           //ecx--,得到字符串2的长度
						"je 7f\n\t"                //(分隔符字符串空)字符串2长度为0,,跳到7
						                           //
						"movl %%ecx,%%edx\n"       //
						"2:\tlodsb\n\t"            //
						"testb %%al,%%al\n\t"      //
						"je 7f\n\t"                //
						"movl %4,%%edi\n\t"        //
						"movl %%edx,%%ecx\n\t"     //
						"repne \n\t"               //
						"scasb \n\t"               //
						"je 2b\n\t"                //
						"decl %1\n\t"              //
						"cmpb $0,(%1)\n\t"         //
						"je 7f\n\t"                //
						"movl %1,%0\n"             //
						"3:\tlodsb\n\t"            //
						"testb %%al,%%al\n\t"      //
						"je 5f\n\t"                //
						"movl %4,%%edi\n\t"        //
						"movl %%edx,%%ecx\n\t"     //
						"repne \n\t"               //
						"scasb \n\t"               //
						"jne 3b\n\t"               //
						"decl %1\n\t"              //
						"cmpb $0,(%1)\n\t"         //
						"je 5f\n\t"                //
						"movb $0,(%1)\n\t"         //
						"incl %1\n\t"              //
						"jmp 6f\n"                 //
						"5:\txorl %1,%1\n"         //
						"6:\tcmpb $0,($0)\n\t"     //
						"jne 7f\n\t"               //
						"xorl %0,%0\n"             //
						"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),"l"(s),"g"(ct)//
						:"ax","cx","dx","di"       //
						);	
						return _res;
}

/*
*内存块复制.从源地址src处开始复制n个字节到目的地址dest处
*参数:dest-目的地址,src-源地址,n-字节数
*%0-ecx(n),%1(esi src),%2(edi dest)
*/
extern inline void * memory()
{
	__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,cost 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)//
								:"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,返回1; 块1<块2,返回-1,块1==块2,返回0
*/
extern inline int memcmp(cosnt void *cs,cosnt 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值
						"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)
*/
extern inline void * memchr(const void*cs,cahr 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指向找到的字符
							:"=D"(_res)                 //
							:"a"(c),"D"(cs),"c"(count)  //
							:"cx"                       //
						                              //
							);	                        //
							return __res;               //
}

/*
*用字符填写指定长度内存块
*用字符c填写s指向的内存区域,共填写count字节
*%1-eax(字符c),%2-edi(内存地址),%3-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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值