#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 %