将参数推入堆栈?

时间:2013-05-02 10:43:16

标签: windows assembly x86-64 masm

我知道前四个参数在寄存器中(RCXRDXR8R9),并且其他参数被压入堆栈。

问题:

如何将参数推入堆栈?我试过(按0)但它不起作用?

代码 MASM64

extrn ExitProcess: PROC   
extrn MessageBoxExA: PROC
.data
caption db '64-bit hello!', 0
message db 'Hello World!', 0
.code
Start PROC
  sub    rsp, 38h        
  mov    rcx, 0         ; hWnd = HWND_DESKTOP
  lea    rdx, message   ; LPCSTR lpText
  lea    r8,  caption   ; LPCSTR lpCaption
  mov    r9d, 0         ; uType = MB_OK

  push   0          ; wLanguageId

  call   MessageBoxExA  
  mov    ecx, eax       
  add    rsp, 38h
  call ExitProcess
Start ENDP
End

我知道MessageBoxMessageBoxEx的工作方式相同,但我尝试使用MessageBoxEx,因为它需要传递一个参数(用于学习目的)。

我知道我已经问了类似的问题,但它与vb.net有关,而事实并非如此。

2 个答案:

答案 0 :(得分:0)

我的程序集有点生疏,但我的印象是所有参数都进入堆栈(按相反的顺序) - 我原以为你想要推送r8和rdx以及其他参数。坦率地说,尽管你可能只是为每个指针参数继续lea rax, parampush rax

答案 1 :(得分:0)

传递参数的顺序以及它们是在寄存器中还是在堆栈中传递(以及调用者或被调用者是否负责清理)由“呼叫约定”定义。

您可能正在考虑的是STDCALL或CDECL,两者都是在32位Windows中使用的调用约定,它以相反的顺序(从右到左)传递堆栈中的参数。 x64已经转移到FastCall调用约定,其中参数以正向顺序(从左到右)传递,前4个参数在寄存器RCX,RDX,R8和&中传递。 R9。超过4的任何参数都以相同的从左到右的顺序传递到堆栈上。原始海报具有使用MASM进行x64汇编的正确调用约定设置。另外,上述响应者表示从RSP中减去的阴影空间应该是20h(32d)是正确的。阴影空间允许堆栈中的空间用于由FastCall中的寄存器传入的4个参数。

将上面的代码更改为:

extrn ExitProcess: PROC   
extrn MessageBoxExA: PROC
.data
caption db '64-bit hello!', 0
message db 'Hello World!', 0
.code

Start PROC
  sub    rsp, 20h        
  mov    rcx, 0         ; hWnd = HWND_DESKTOP
  lea    rdx, message   ; LPCSTR lpText
  lea    r8,  caption   ; LPCSTR lpCaption
  mov    r9d, 0         ; uType = MB_OK

  push   0          ; wLanguageId

  call   MessageBoxExA  
  mov    ecx, eax       
  add    rsp, 20h
  call ExitProcess
Start ENDP
End

在64位计算机上的Visual Studio中运行良好