我知道前四个参数在寄存器中(RCX、RDX、R8、R9),另外的参数被推到堆栈上。
问题:
如何将参数推到堆栈上?我试过(推送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我知道MessageBox和MessageBoxEx的工作方式相同,但我尝试使用MessageBoxEx,因为它需要传递一个参数(用于学习目的)。
我知道我也问过类似的问题,但它更多的是与vb.net有关,而这不是。
发布于 2013-05-02 11:02:07
我的程序集有点生疏,但我的印象是所有的参数都进入堆栈(按相反的顺序)--我认为您想把r8和rdx以及其他参数都推进去。坦率地说,您最好还是继续对每个作为指针的参数执行lea rax, param和push rax。
发布于 2014-11-11 06:17:13
参数传递的顺序以及它们是否在寄存器或堆栈中传递(以及调用方或被调用者是否负责清理)由“调用约定”定义。
您可能想到的是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中工作得很好。
https://stackoverflow.com/questions/16336019
复制相似问题