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
相关产品推荐
相关产品推荐

