在字符串中查找指定字符的第一次出现位置strchr

static inline char * strchr(const char * s, int c)
{
int d0;
register char * __res;
__asm__ __volatile__(
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"movl $1,%1\n"
"2:\tmovl %1,%0\n\t"
"decl %0"
:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
return __res;
}

1. 函数功能概述

这是一个用内联汇编实现的 strchr 函数,用于在字符串中查找指定字符的第一次出现位置

2. 代码分段详解

2.1. 第一段:函数声明和变量定义

static inline char *strchr(const char *s, int c)
{
int d0;
register char *__res;
  • static inline 表示这是内联函数,调用时直接展开而不是函数调用
  • const char *s 是输入字符串指针
  • int c 是要查找的字符
  • int d0 用于存储临时值(在汇编中作为占位符)
  • register char *__res 声明寄存器变量,用于存储结果指针

2.2. 第二段:内联汇编开始和初始设置

__asm__ __volatile__(
"movb %%al,%%ah\n\t"
  • __asm__ __volatile__ 开始内联汇编块,volatile 表示禁止编译器优化
  • movb %%al,%%ah 将字符 c(在 al 寄存器中)复制到 ah 寄存器中备份
    • %%al 对应参数 c(通过约束条件 “0” 传入)
    • 备份是因为 lodsb 指令会修改 al 寄存器

2.2. 第三段:字符串扫描循环

"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
  • 1:\tlodsb 标签1:加载字符串字节到 al,同时递增 esi 指针
  • cmpb %%ah,%%al 比较当前字符(al)与目标字符(ah
  • je 2f 如果相等,跳转到标签2
  • testb %%al,%%al 测试当前字符是否为0(字符串结束)
  • jne 1b 如果不是0,跳转回标签1(向后跳转),继续循环

2.3. 第四段:处理查找失败情况

"movl $1,%1\n\t"
  • movl $1,%1 将1移动到操作数1(d0 变量)
  • 这行代码只在查找失败(到达字符串末尾未找到字符)时执行

2.4. 第五段:处理查找成功情况

"2:\tmovl %1,%0\n\t"
"decl %0"
  • 2:\tmovl %1,%0 标签2:将操作数1(d0esi)的值复制到操作数0(__res
  • decl %0 递减结果指针(因为 lodsb 在比较后自动递增了指针)

2.5. 第六段:汇编约束条件

: "=a" (__res), "=&S" (d0)
: "1" (s), "0" (c));

输出操作数:

  • "=a" (__res)__res 变量绑定到 eax 寄存器(= 表示只写)
  • "=&S" (d0)d0 变量绑定到 esi 寄存器(& 表示早期破坏)

输入操作数:

  • "1" (s):输入字符串 s 使用与操作数1相同的约束(即 esi 寄存器)
  • "0" (c):输入字符 c 使用与操作数0相同的约束(即 eax 寄存器)

2.6. 第七段:函数返回

return __res;
}
  • 返回查找到的字符指针,如果未找到则返回 NULL

3. 函数工作流程图

相等
不相等
是0,字符串结束
不是0
开始strchr
备份字符c到ah
lodsb加载字符到al
比较al和ah
跳转到成功处理
测试al是否为0
设置d0=1查找失败
继续循环
返回NULL
调整指针位置
返回找到的指针

4. 寄存器使用说明

寄存器用途
eax (al/ah)al 存储当前字符,ah 存储目标字符
esi字符串扫描指针
__res结果指针(通过 eax 返回)

5. 汇编指令详解

  • lodsb:从 [esi] 加载字节到 al,同时 esi 自动加1
  • cmpb:比较两个字节
  • testb:测试字节值(常用于检测是否为0)
  • je/jne:条件跳转(相等/不相等)
  • movb/movl:移动字节/双字
  • decl:递减

6. 函数功能总结

主要功能:在字符串 s 中查找字符 c 的第一次出现位置

返回值

  • 成功:指向找到字符的指针
  • 失败:NULL 指针

特点

  • 使用内联汇编实现,效率高
  • 直接操作寄存器,避免函数调用开销
  • 使用 lodsb 指令高效遍历字符串
  • 正确处理字符串终止符检测

这个实现展示了如何用汇编语言高效实现字符串操作,特别适合在内核等性能敏感的场景中使用。