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

NASM x86_64中保存返回地址到寄存器再入栈是否可行?

你的汇编_write函数实现问题解答

可行性判断

这种实现是可行的,代码能正常完成输出功能:

  • 调用_write前,你按顺序把字符串指针、长度压入栈,手动实现了栈传参的规则(x86_64默认用寄存器传参,但自定义栈传参逻辑完全合法)
  • 进入_write后,先把call指令压入栈的返回地址暂存到r8,此时栈顶正好是你传入的参数,依次弹出长度到rdx、指针到rsi,然后正确调用sys_write系统调用(rax=1对应写操作,rdi=1指定标准输出,参数匹配正确)
  • 最后把返回地址重新压回栈,执行ret指令能准确回到调用点,继续后续的退出系统调用。实际运行这段代码会正常输出Hello world!。

栈结构是否被破坏

不会破坏栈结构,整个过程栈的平衡完全维护好了:

  • 调用_write前,栈中压入了两个8字节参数(x86_64下指针和立即数都按8字节处理),加上call指令自动压入的8字节返回地址,进入_write时栈里共有24字节数据。
  • 函数内先弹出返回地址到r8(栈减少8字节),再弹出两个参数(共减少16字节),此时栈回到调用call之前的状态;随后把返回地址压回栈,执行ret时弹出这个地址,栈最终完全恢复到调用_write前的状态,没有任何栈溢出或残留问题。

初学者注意事项

  • 你用的是x86_64汇编,栈操作单位是8字节,你的参数都是8字节长度,pop/push操作没有字节不匹配的问题,这一点处理得很正确。
  • 虽然当前实现可行,但用rbp(帧指针)访问参数的方式确实更优:进入函数后执行push rbp; mov rbp, rsp,就能通过rbp+8、rbp+16直接定位参数,不需要移动返回地址,代码可读性和可维护性更高,也不容易出错。
  • 补充:x86_64 Linux系统调用的参数传递规则是rax存调用号,rdi、rsi、rdx依次传前三个参数,你这里sys_write的参数对应完全正确,这点没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:35:41