📄 string.h
字号:
"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 intstrspn (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 intstrcsrcpn (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 intstrlen (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" // 若不相等就一直比较。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -