You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

strchr()函数实现问题:汇编重写触发0x0段错误及调试困惑

修复strchr实现中的段错误与逻辑问题

我来帮你排查一下这个strchr实现里的问题,你碰到的段错误和逻辑bug主要有两处:

1. 未初始化的rcx导致非法内存访问

在good标签的代码里,你写了mov rax, [rdi + rcx],但整个程序里从来没有给rcx赋过值!rcx的初始值是随机的垃圾值,这会导致你去访问一个完全不确定的内存地址,大概率触发段错误(尤其是当这个随机地址指向0x0附近时)。

实际上你一直在用rax记录当前遍历的偏移量,所以这里应该用rax来计算目标地址,改成lea rax, [rdi + rax](直接用lea指令计算地址,比mov+add更高效)就对了。

2. 查找\0的逻辑顺序错误

strchr的标准语义是:如果要查找的字符是\0,需要返回字符串末尾那个\0的地址。但你的代码里先判断当前字符是否为0,一旦是就跳去end返回空指针,之后才判断要找的字符是不是0——这就导致当用户传入要找的字符是\0时,你直接返回了空指针,完全不符合预期。

正确的顺序应该是:先判断当前字符是否匹配目标字符(包括目标字符是\0的情况),再判断是否到了字符串末尾。

修正后的完整代码

.section .text
global strchr
strchr:
    xor rax, rax          ; 初始化遍历偏移量为0
loop:
    mov cl, BYTE [rdi + rax]  ; 读取当前字符到cl,避免重复访问内存
    cmp cl, sil           ; 比较当前字符与目标字符sil
    jz good               ; 匹配成功,跳转到返回地址的逻辑
    cmp cl, 0             ; 未匹配,判断是否到字符串末尾
    jz end                ; 到末尾且未找到,返回空指针
    inc rax               ; 偏移量+1,继续下一次循环
    jmp loop
good:
    lea rax, [rdi + rax]  ; 计算目标字符的地址:起始地址+偏移量
    ret
end:
    xor rax, rax          ; 返回空指针(比mov rax,0更高效)
    ret

额外优化说明

  • 把当前字符先读到cl里,避免了原代码中两次访问[rdi+rax]的重复内存操作,提升了效率
  • 用xor rax, rax代替mov rax, 0,是汇编里的常用小技巧,指令长度更短,执行效率更高
  • 调整了判断顺序,完美符合strchr的标准行为:无论目标字符是普通字符还是\0,都能正确返回对应的地址

内容的提问来源于stack exchange,提问作者C.Edelweiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:33:14