汇编实现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
相关产品推荐
相关产品推荐

