string.h ( File view )

  • By 2010-08-31
  • View(s):24
  • Download(s):2
  • Point(s): 1
			#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=数据空间,这应该是常规的。绝大多数字符串函数都是经手工进行大量
* 优化的,尤其是函数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__ ("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)。
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__ ("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)。
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;			// 返回目的字符串指针。

}

//// 将一个字符串与另一个字符串进行比较。
// 参数:cs - 字符串1,ct - 字符串2。
// %0 - eax(__res)返回值,%1 - edi(cs)字符串1 指针,%2 - esi(ct)字符串2 指针。
// 返回:如果串1 > 串2,则返回1;串1 = 串2,则返回0;串1 < 串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]??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" (cs), "S" (ct):"si", "di");
  return __res;			// 返回比较结果。

}

//// 字符串1 与字符串2 的前count 个字符进行比较。
// 参数:cs - 字符串1,ct - 字符串2,count - 比较的字符数。
// %0 - eax(__res)返回值,%1 - edi(cs)串1 指针,%2 - esi(ct)串2 指针,%3 - ecx(count)。
// 返回:如果串1 > 串2,则返回1;串1 = 串2,则返回0;串1 < 串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]??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" (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]??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)。
// 返回:返回字符串中最后一次出现匹配字符的指针。若没有找到匹配的字符,则返回空指针。
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 个字符序列,该字符序列
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 1

Download
0 lines left, continue to read
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
linux0.00 B0% 04-10-07
<boot>0.00 B04-10-07 15:01
bootsect.s12.49 kB08-01-04 21:38
head.s13.22 kB08-01-04 21:38
setup.s12.42 kB08-01-04 21:38
<fs>0.00 B04-10-07 15:01
bitmap.c8.46 kB02-09-04 13:12
block_dev.c3.95 kB02-09-04 13:12
buffer.c17.71 kB02-09-04 13:12
char_dev.c4.09 kB02-09-04 13:12
exec.c18.90 kB02-09-04 13:12
fcntl.c3.33 kB02-09-04 13:12
file_dev.c4.82 kB02-09-04 13:12
file_table.c209.00 B02-09-04 13:12
inode.c14.92 kB02-09-04 13:12
ioctl.c1.94 kB02-09-04 13:12
Makefile6.80 kB08-01-04 21:45
namei.c37.20 kB02-09-04 13:12
open.c10.00 kB02-09-04 13:12
pipe.c5.42 kB02-09-04 13:12
read_write.c5.86 kB02-09-04 13:12
stat.c2.69 kB02-09-04 13:12
super.c13.57 kB02-09-04 13:12
truncate.c2.46 kB02-09-04 13:12
<include>0.00 B04-10-07 15:01
a.out.h8.22 kB02-09-04 13:14
<asm>0.00 B04-10-07 15:01
io.h772.00 B02-09-04 13:14
memory.h1.03 kB08-01-04 22:13
segment.h2.50 kB02-09-04 13:14
system.h4.08 kB02-09-04 13:14
const.h589.00 B02-09-04 13:14
ctype.h1.68 kB02-09-04 13:14
errno.h2.30 kB02-09-04 13:14
fcntl.h3.30 kB02-09-04 13:14
<linux>0.00 B04-10-07 15:01
config.h2.16 kB02-09-04 13:14
fs.h9.72 kB02-09-04 13:14
hdreg.h2.94 kB02-09-04 13:14
head.h760.00 B02-09-04 13:14
kernel.h1.44 kB02-09-04 13:14
mm.h473.00 B02-09-04 13:14
sched.h13.25 kB02-09-04 13:14
sys.h5.41 kB02-09-04 13:14
tty.h3.93 kB02-09-04 13:14
signal.h4.01 kB02-09-04 13:14
stdarg.h1.77 kB02-09-04 13:14
stddef.h378.00 B02-09-04 13:14
string.h21.75 kB02-09-04 13:14
<sys>0.00 B04-10-07 15:01
stat.h2.37 kB02-09-04 13:14
times.h377.00 B02-09-04 13:14
types.h1.10 kB02-09-04 13:14
utsname.h423.00 B02-09-04 13:14
wait.h1.48 kB02-09-04 13:14
termios.h13.58 kB02-09-04 13:14
time.h1.81 kB02-09-04 13:14
unistd.h9.21 kB02-09-04 13:14
utime.h392.00 B02-09-04 13:14
<init>0.00 B04-10-07 15:01
main.c12.52 kB02-09-04 13:12
<kernel>0.00 B04-10-07 15:01
asm.s5.10 kB08-01-04 22:48
<blk_drv>0.00 B04-10-07 15:01
blk.h5.69 kB02-09-04 13:14
floppy.c23.49 kB02-09-04 13:12
hd.c17.14 kB02-09-04 13:12
ll_rw_blk.c7.59 kB02-09-04 13:12
Makefile4.25 kB08-01-04 22:53
ramdisk.c6.13 kB02-09-04 13:12
<chr_drv>0.00 B04-10-07 15:01
console.c30.91 kB02-09-04 13:12
keyboard.S21.04 kB08-01-04 22:59
Makefile4.81 kB08-01-04 22:59
rs_io.s5.75 kB08-01-04 22:59
serial.c2.91 kB02-09-04 13:12
tty_io.c18.40 kB02-09-04 13:12
tty_ioctl.c10.70 kB02-09-04 13:12
exit.c8.08 kB02-09-04 13:12
fork.c6.78 kB15-07-07 22:10
<math>0.00 B04-10-07 15:01
Makefile3.21 kB08-01-04 23:01
math_emulate.c2.08 kB02-09-04 13:12
mktime.c2.72 kB02-09-04 13:12
panic.c952.00 B02-09-04 13:12
printk.c1.75 kB02-09-04 13:12
sched.c18.57 kB16-07-07 21:23
signal.c5.61 kB02-09-04 13:12
sys.c7.62 kB02-09-04 13:12
system_call.s12.53 kB08-01-04 22:48
traps.c8.29 kB04-10-07 14:57
vsprintf.c9.96 kB02-09-04 13:12
<lib>0.00 B04-10-07 15:01
close.c397.00 B02-09-04 13:12
ctype.c1.72 kB02-09-04 13:12
dup.c401.00 B02-09-04 13:12
errno.c66.00 B02-09-04 13:12
execve.c607.00 B02-09-04 13:12
Makefile4.83 kB08-01-04 22:30
malloc.c13.50 kB02-09-04 13:12
open.c1.22 kB02-09-04 13:12
setsid.c382.00 B02-09-04 13:12
string.c199.00 B02-09-04 13:12
wait.c774.00 B02-09-04 13:12
write.c545.00 B02-09-04 13:12
_exit.c616.00 B02-09-04 13:12
Makefile8.58 kB08-01-04 22:21
<mm>0.00 B04-10-07 15:01
Makefile2.91 kB08-01-04 22:34
memory.c25.10 kB02-09-04 13:12
page.s842.00 B08-01-04 22:34
<tools>0.00 B04-10-07 15:01
build.c8.12 kB02-09-04 13:12
...
Sponsored links

string.h (286.77 kB)

Need 1 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D