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

x64 FastCall调用栈管理疑问:Invoke宏为何用RBP而非Push?

x64汇编调用CreateFileW的参数传递疑问

问题背景

根据MSDN的x64调用约定:

  • 最左侧4个整型参数依次通过RCX、RDX、R8、R9寄存器传递;
  • 调用者需分配32字节的阴影存储,供被调用者保存寄存器;
  • 剩余参数按从右到左的顺序入栈;
  • 调用前栈指针RSP必须保持16字节对齐。

我手动编写了调用CreateFileW的代码,可汇编但运行报错(错误码0x57,参数无效):

sub rsp, 20h             ; 分配32字节阴影存储
mov rcx, offset filename ; lpFileName
mov rdx, GENERIC_READ or GENERIC_WRITE ; dwDesiredAccess
mov r8, FILE_SHARE_DELETE              ; dwShareMode
xor r9, r9                             ; LpSecurityAttributes
; 剩余参数按从右到左入栈
push 0 ; hTemplateFile
push FILE_ATTRIBUTE_NORMAL             ; dwFlagsAndAttributes
push CREATE_ALWAYS                     ; dwCreationDisposition
call CreateFileW

但使用俄罗斯MASM64 SDK的Invoke宏生成的代码却能正常运行,代码如下:

mov rcx,src.403000    ; name          
mov edx,C0000000      ; GENERIC_READ or GENERIC_WRITE                  
mov r8d,4             ; FILE_SHARE_DELETE                  
xor r9d,r9d           ; 0                  
mov qword ptr ss:[rbp-20],2 ; CREATE_ALWAYS           
mov qword ptr ss:[rbp-18],80 ; FILE_ATTRIBUTE_NORMAL          
mov qword ptr ss:[rbp-10],0  ; hTemplateFile           
call qword ptr ds:[<&CreateFileW>]   

我的疑问是:为什么宏生成的代码用RBP而非push指令存储剩余参数,且看不到显式的32字节阴影存储分配?


解答

1. 为何用RBP而非PUSH存储剩余参数?

宏选择基于RBP的栈帧方式存储参数,而非直接push,原因有三点:

  • 调试友好:以RBP为基址的固定偏移能让调试器更方便地定位参数,避免push导致栈指针频繁波动带来的参数定位困难;
  • 栈对齐稳定:x64调用约定要求调用前RSP必须是16字节对齐,push指令每次会让RSP减8,若剩余参数数量为奇数,会破坏16字节对齐;而通过RBP偏移写入参数,能精准控制栈布局,确保对齐要求;
  • 代码健壮性:当参数数量较多或需要修改参数时,栈帧方式比多次push更易维护,不易出错。

2. 为何看不到显式的32字节阴影存储分配?

宏生成的代码依赖栈帧结构,阴影存储的分配是在函数的序言(Prologue)阶段完成的,而非显式的sub rsp, 20h:

  • 通常函数序言会包含push rbp; mov rbp, rsp,之后会通过sub rsp, xx分配足够的栈空间,其中已经包含了32字节的阴影存储,以及剩余参数所需的空间;
  • 你看到的[rbp-20]、[rbp-18]等偏移,已经包含了阴影存储的32字节(0x20),剩余参数实际存储在阴影存储之后的栈区域中。

补充:你的手动代码报错原因

你的代码报错本质是栈对齐不符合要求:

  • 调用call指令前,RSP必须是16字节对齐(因为call会压入8字节的返回地址,压入后RSP仍需保持16字节对齐);
  • 你执行sub rsp, 20h后,RSP是16字节对齐的,但连续push3个参数(每个占8字节)后,RSP的偏移为20h + 3*8h = 38h,此时RSP % 16 = 8,破坏了16字节对齐,导致CreateFileW因参数布局错误返回无效参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:55:44