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

如何在MASM x64环境下将参数压入栈?

问题解答

核心问题原因

你遇到的崩溃、参数异常问题根源是没有遵守Windows x64调用约定的核心规则:

  • 调用者需要为被调函数预留32字节的影子空间(Shadow Space),用于被调函数备份前4个寄存器参数(rcx/rdx/r8/r9),哪怕被调函数实际不会用到这部分空间也必须预留
  • 执行call指令前,栈指针rsp必须对齐到16字节边界
  • 额外的栈参数需要放在影子空间的上方,你之前直接写[rsp + 20h]时没有预留栈空间,写入的地址刚好覆盖了当前函数的返回地址,所以执行ret时会把写入的参数值当成返回地址加载到rip,导致RIP变成异常值。

正确实现步骤

  1. 进入函数后先保存非易失寄存器、设置栈帧,再分配足够的栈空间:需要包含32字节影子空间 + 你要传递的额外参数的总空间,同时保证分配后rsp满足16字节对齐要求
  2. 额外的第N个参数(N≥5)写入影子空间后的对应偏移位置
  3. 调用结束后恢复栈空间和非易失寄存器
    你场景的正确汇编代码如下:
call_func PROC
    push rbx        ; rbx是被调保护的非易失寄存器,修改前先保存
    push rbp
    mov rbp, rsp
    sub rsp, 30h    ; 分配48字节栈空间:32字节影子空间 + 2个8字节参数位(支持最多6个参数),同时满足16字节对齐

    mov rbx, rcx    ; 保存要调用的C函数地址

    ; 前4个参数写入对应寄存器
    mov rcx, 1
    mov rdx, 2
    mov r8, 3
    mov r9, 4
    ; 第5个参数写入影子空间后第一个位置
    mov QWORD PTR [rsp + 20h], 5
    ; 第6个参数写入下一个8字节位置(有需要时加)
    mov QWORD PTR [rsp + 28h], 6

    call rbx        ; 调用目标函数

    mov rsp, rbp    ; 恢复栈指针
    pop rbp
    pop rbx         ; 恢复rbx寄存器原值
    ret
call_func ENDP

异常情况说明

你之前测试6个参数时第6个传递成功、第5个异常,是因为你写入[rsp + 28h]时刚好没有覆盖返回地址,但第5个参数对应的位置没有预留空间,被栈上其他原有数据覆盖,才会出现取值异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:18:03