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

汇编实现strdup代码评审请求:栈空间处理疑问及优化建议

汇编实现strdup的代码评审与优化建议

栈操作正确性确认

你的代码中通过RSP预留栈空间和恢复栈的操作是正确的:

  • 进入函数后,push rbp使栈偏移8字节,随后sub rsp,8将栈调整回16字节对齐(符合x86-64 System V调用约定的栈对齐要求),用[rbp-8]保存源字符串指针rdi的逻辑没问题。
  • 正常路径和错误路径中都执行了add rsp,8和pop rbp,栈空间被正确恢复,不会出现栈泄漏或栈不平衡的问题。

优化建议

1. 简化栈帧,直接用push保存寄存器

无需手动通过sub rsp预留栈空间,直接用push rdi保存源指针,既简洁又自动维护栈对齐:

_ft_strdup:
    push        rbp
    mov         rbp, rsp
    push        rdi  ; 直接将源指针压栈保存,替代sub rsp+内存写入操作
    call        _ft_strlen
    mov         rdi, rax
    call        malloc
    ; ... 后续逻辑

2. 合并退出路径,消除冗余代码

当前正常路径和错误路径的栈恢复代码重复,可以将退出逻辑合并,同时用更高效的指令判断malloc失败:

extern malloc
extern _ft_strlen
extern _ft_strcpy

section .text
    global  _ft_strdup

_ft_strdup:
    push        rbp
    mov         rbp, rsp
    push        rdi          ; 保存源字符串指针

    call        _ft_strlen
    mov         rdi, rax
    call        malloc

    test        rax, rax     ; 用test替代cmp rax,0,指令更高效
    jz          .error_exit

    mov         rdi, rax
    pop         rsi          ; 直接从栈弹出保存的源指针到rsi,省去内存访问
    call        _ft_strcpy

    pop         rbp
    ret

.error_exit:
    xor         rax, rax
    add         rsp, 8       ; 弹出之前压栈的rdi
    pop         rbp
    ret

3. 减少内存访问,提升效率

原代码中先将rdi写入栈内存,后续又从内存加载到rsi,改用push rdi + pop rsi的方式,减少一次内存读写操作,性能更优。

4. 保持调用约定一致性

确认_ft_strlen(接收rdi参数,返回长度到rax)和_ft_strcpy(rdi=目标地址,rsi=源地址,返回目标地址到rax)完全遵循x86-64 System V调用约定,你的代码当前已经符合要求,无需调整。

内容的提问来源于stack exchange,提问作者user18129922

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:45:23