在堆栈上传递的参数不会传递给被调用的函数
Arguments passed on the stack aren't being passed to the called function
我正在使用 nasm、cl.exe 和 win32 API 调用在 x86-64 程序集中为 windows 编写游戏。我的应用程序成功创建了 window,但它的大小和位置不正确(它很高但水平方向很窄)。
这是我创建 window 的代码部分,并在使用 GetModuleHandleA(NULL)
获得 HINSTANCE
并注册 window [=33] 后显示它=] 与 RegisterClassA
.
; Create The Window
mov RCX, 0 ; dwExStyle
mov RDX, WindowClassName ; lpClassName
MOV R8, WindowName ; lpWindowName
MOV R9, 13565952 ; dwStyle
sub rsp, 48
mov qword[rbp - 48], 0 ; lpParam
mov RAX, qword[HINSTANCE] ;
mov qword[rbp - 40], RAX ; hInstance
mov qword[rbp - 32], 0 ; hMenu
mov qword[rbp - 24], 0 ; hWndParent
mov dword[rbp - 16], 1080 ; nHeight
mov dword[rbp - 12], 1920 ; nWidth
mov dword[rbp - 8], 100 ; Y
mov dword[rbp - 4], 100 ; X
call CreateWindowExA
mov qword[HWND], RAX ; Save the window handle
; Show The Window
mov RCX, qword[HWND]
mov RDX, 5 ; SW_SHOW
call ShowWindow
我在二进制忍者中查看了它,我向我展示了只有前 6 个参数被传递给 CreateWindowExA
。我查看了 Microsoft's x64 calling convention,但没有发现任何错误。
根据它,参数是这样传递的:
CreateWindowExA(dwExStyle: 0, lpClassName: 0x403010, lpWindowName: 0x403023, dwStyle: 0xcf0000, X: 0x438, Y: 0x64)
。我确实注意到 X 的值是错误的,但我也不明白为什么。
在此先感谢您能给我的任何帮助!
如果有帮助,这是我的完整代码:
global _start
extern GetModuleHandleA
extern RegisterClassA
extern DefWindowProcA
extern CreateWindowExA
extern ShowWindow
extern PeekMessageA
extern TranslateMessage
extern DispatchMessageA
section .text
_start:
; Prologue
push rbp
mov rbp, rsp
; Get hInstance
xor RCX, RCX
call GetModuleHandleA
mov qword[HINSTANCE], RAX ; Save hInstance
; Register The Window Class
mov dword[WNDCLASSA], 3 ; style
mov qword[WNDCLASSA + 8], DefWindowProcA ; lpfnWndProc
mov dword[WNDCLASSA + 12], 0 ; cbClsExtra
mov dword[WNDCLASSA + 16], 0 ; cbWndExtra
mov RAX, qword[HINSTANCE]
mov qword[WNDCLASSA + 24], RAX ; hInstance
mov qword[WNDCLASSA + 32], 0 ; hIcon
mov qword[WNDCLASSA + 40], 0 ; hCursor
mov qword[WNDCLASSA + 48], 0 ; hbrBackground
mov qword[WNDCLASSA + 56], 0 ; lpszMenuName
mov qword[WNDCLASSA + 64], WindowClassName ; lpszClassName
lea RCX, WNDCLASSA
call RegisterClassA
; Create The Window
mov RCX, 0 ; dwExStyle
mov RDX, WindowClassName ; lpClassName
MOV R8, WindowName ; lpWindowName
MOV R9, 13565952 ; dwStyle
sub rsp, 48
mov qword[rbp - 48], 0 ; lpParam
mov RAX, qword[HINSTANCE] ;
mov qword[rbp - 40], RAX ; hInstance
mov qword[rbp - 32], 0 ; hMenu
mov qword[rbp - 24], 0 ; hWndParent
mov dword[rbp - 16], 1080 ; nHeight
mov dword[rbp - 12], 1920 ; nWidth
mov dword[rbp - 8], 100 ; Y
mov dword[rbp - 4], 100 ; X
call CreateWindowExA
mov qword[HWND], RAX ; Save the window handle
; Show The Window
mov RCX, qword[HWND]
mov RDX, 5
call ShowWindow
a:
jmp a
; Message Loop
message_loop:
LEA RCX, MSG
mov RDX, qword[HWND]
mov R8, 0
mov R9, 0
sub rsp, 4
mov dword[rbp - 4], 1
call PeekMessageA
LEA RCX, MSG
call TranslateMessage
LEA RCX, MSG
call DispatchMessageA
jmp message_loop
; Epilogue
mov rsp, rbp
pop rbp
ret
section .data
HINSTANCE dq 0
HWND dq 0
WindowClassName db 'Polar Window Class', 0
WindowName db 'Polar Window', 0
section .bss
WNDCLASSA resb 72
MSG resb 48
我的代码有很多问题,所以我找不到所有问题都得到解决的问题。结果,这就是我如何在评论的帮助下解决我的问题(谢谢)。我没有分配 shadow space 并且我没有将我放在堆栈上的参数对齐到 8 个字节。我的汇编代码现在看起来像这样(未优化且没有异常处理):
global _start
extern GetModuleHandleA
extern RegisterClassA
extern DefWindowProcA
extern CreateWindowExA
extern ShowWindow
extern PeekMessageA
extern TranslateMessage
extern DispatchMessageA
section .text
_start:
; Prologue
push rbp
mov rbp, rsp
; Get hInstance
xor RCX, RCX
call GetModuleHandleA
mov qword[HINSTANCE], RAX ; Save hInstance
; Register The Window Class
mov dword[WNDCLASSA], 3 ; style
mov qword[WNDCLASSA + 8], DefWindowProcA ; lpfnWndProc
mov dword[WNDCLASSA + 12], 0 ; cbClsExtra
mov dword[WNDCLASSA + 16], 0 ; cbWndExtra
mov RAX, qword[HINSTANCE]
mov qword[WNDCLASSA + 24], RAX ; hInstance
mov qword[WNDCLASSA + 32], 0 ; hIcon
mov qword[WNDCLASSA + 40], 0 ; hCursor
mov qword[WNDCLASSA + 48], 0 ; hbrBackground
mov qword[WNDCLASSA + 56], 0 ; lpszMenuName
mov qword[WNDCLASSA + 64], WindowClassName ; lpszClassName
lea RCX, WNDCLASSA
sub rsp, 0x20 ; Shadow Space
call RegisterClassA
add rsp, 0x20 ; Shadow Space
; Create The Window
xor RCX, RCX ; dwExStyle
mov RDX, WindowClassName ; lpClassName
MOV R8, WindowName ; lpWindowName
MOV R9, 13565952 ; dwStyle
sub rsp, 96
mov qword[rsp + 20h + 56], 0 ; lpParam
mov RAX, qword[HINSTANCE] ;
mov qword[rsp + 20h + 48], RAX ; hInstance
mov qword[rsp + 20h + 40], 0 ; hMenu
mov qword[rsp + 20h + 32], 0 ; hWndParent
mov qword[rsp + 20h + 24], 1080 ; nHeight
mov qword[rsp + 20h + 16], 1920 ; nWidth
mov qword[rsp + 20h + 8], 100 ; Y
mov qword[rsp + 20h], 100 ; X
call CreateWindowExA
add rsp, 96
mov qword[HWND], RAX ; Save the window handle
; Show The Window
sub rsp, 0x20
mov RCX, qword[HWND]
mov RDX, 5
call ShowWindow
add rsp, 0x20
; Message Loop
message_loop:
sub rsp, 48
LEA RCX, [MSG]
mov RDX, qword[HWND]
mov R8, 0
mov R9, 0
mov qword[rsp + 20h], 1
call PeekMessageA
add rsp, 48
sub rsp, 32
LEA RCX, [MSG]
call TranslateMessage
LEA RCX, [MSG]
call DispatchMessageA
add rsp, 32
jmp message_loop
; Epilogue
mov rsp, rbp
pop rbp
ret
section .data
HINSTANCE dq 0
HWND dq 0
WindowClassName db 'Polar Window Class', 0
WindowName db 'Polar Window', 0
section .bss
WNDCLASSA resb 72
MSG resb 48
我正在使用 nasm、cl.exe 和 win32 API 调用在 x86-64 程序集中为 windows 编写游戏。我的应用程序成功创建了 window,但它的大小和位置不正确(它很高但水平方向很窄)。
这是我创建 window 的代码部分,并在使用 GetModuleHandleA(NULL)
获得 HINSTANCE
并注册 window [=33] 后显示它=] 与 RegisterClassA
.
; Create The Window
mov RCX, 0 ; dwExStyle
mov RDX, WindowClassName ; lpClassName
MOV R8, WindowName ; lpWindowName
MOV R9, 13565952 ; dwStyle
sub rsp, 48
mov qword[rbp - 48], 0 ; lpParam
mov RAX, qword[HINSTANCE] ;
mov qword[rbp - 40], RAX ; hInstance
mov qword[rbp - 32], 0 ; hMenu
mov qword[rbp - 24], 0 ; hWndParent
mov dword[rbp - 16], 1080 ; nHeight
mov dword[rbp - 12], 1920 ; nWidth
mov dword[rbp - 8], 100 ; Y
mov dword[rbp - 4], 100 ; X
call CreateWindowExA
mov qword[HWND], RAX ; Save the window handle
; Show The Window
mov RCX, qword[HWND]
mov RDX, 5 ; SW_SHOW
call ShowWindow
我在二进制忍者中查看了它,我向我展示了只有前 6 个参数被传递给 CreateWindowExA
。我查看了 Microsoft's x64 calling convention,但没有发现任何错误。
根据它,参数是这样传递的:
CreateWindowExA(dwExStyle: 0, lpClassName: 0x403010, lpWindowName: 0x403023, dwStyle: 0xcf0000, X: 0x438, Y: 0x64)
。我确实注意到 X 的值是错误的,但我也不明白为什么。
在此先感谢您能给我的任何帮助!
如果有帮助,这是我的完整代码:
global _start
extern GetModuleHandleA
extern RegisterClassA
extern DefWindowProcA
extern CreateWindowExA
extern ShowWindow
extern PeekMessageA
extern TranslateMessage
extern DispatchMessageA
section .text
_start:
; Prologue
push rbp
mov rbp, rsp
; Get hInstance
xor RCX, RCX
call GetModuleHandleA
mov qword[HINSTANCE], RAX ; Save hInstance
; Register The Window Class
mov dword[WNDCLASSA], 3 ; style
mov qword[WNDCLASSA + 8], DefWindowProcA ; lpfnWndProc
mov dword[WNDCLASSA + 12], 0 ; cbClsExtra
mov dword[WNDCLASSA + 16], 0 ; cbWndExtra
mov RAX, qword[HINSTANCE]
mov qword[WNDCLASSA + 24], RAX ; hInstance
mov qword[WNDCLASSA + 32], 0 ; hIcon
mov qword[WNDCLASSA + 40], 0 ; hCursor
mov qword[WNDCLASSA + 48], 0 ; hbrBackground
mov qword[WNDCLASSA + 56], 0 ; lpszMenuName
mov qword[WNDCLASSA + 64], WindowClassName ; lpszClassName
lea RCX, WNDCLASSA
call RegisterClassA
; Create The Window
mov RCX, 0 ; dwExStyle
mov RDX, WindowClassName ; lpClassName
MOV R8, WindowName ; lpWindowName
MOV R9, 13565952 ; dwStyle
sub rsp, 48
mov qword[rbp - 48], 0 ; lpParam
mov RAX, qword[HINSTANCE] ;
mov qword[rbp - 40], RAX ; hInstance
mov qword[rbp - 32], 0 ; hMenu
mov qword[rbp - 24], 0 ; hWndParent
mov dword[rbp - 16], 1080 ; nHeight
mov dword[rbp - 12], 1920 ; nWidth
mov dword[rbp - 8], 100 ; Y
mov dword[rbp - 4], 100 ; X
call CreateWindowExA
mov qword[HWND], RAX ; Save the window handle
; Show The Window
mov RCX, qword[HWND]
mov RDX, 5
call ShowWindow
a:
jmp a
; Message Loop
message_loop:
LEA RCX, MSG
mov RDX, qword[HWND]
mov R8, 0
mov R9, 0
sub rsp, 4
mov dword[rbp - 4], 1
call PeekMessageA
LEA RCX, MSG
call TranslateMessage
LEA RCX, MSG
call DispatchMessageA
jmp message_loop
; Epilogue
mov rsp, rbp
pop rbp
ret
section .data
HINSTANCE dq 0
HWND dq 0
WindowClassName db 'Polar Window Class', 0
WindowName db 'Polar Window', 0
section .bss
WNDCLASSA resb 72
MSG resb 48
我的代码有很多问题,所以我找不到所有问题都得到解决的问题。结果,这就是我如何在评论的帮助下解决我的问题(谢谢)。我没有分配 shadow space 并且我没有将我放在堆栈上的参数对齐到 8 个字节。我的汇编代码现在看起来像这样(未优化且没有异常处理):
global _start
extern GetModuleHandleA
extern RegisterClassA
extern DefWindowProcA
extern CreateWindowExA
extern ShowWindow
extern PeekMessageA
extern TranslateMessage
extern DispatchMessageA
section .text
_start:
; Prologue
push rbp
mov rbp, rsp
; Get hInstance
xor RCX, RCX
call GetModuleHandleA
mov qword[HINSTANCE], RAX ; Save hInstance
; Register The Window Class
mov dword[WNDCLASSA], 3 ; style
mov qword[WNDCLASSA + 8], DefWindowProcA ; lpfnWndProc
mov dword[WNDCLASSA + 12], 0 ; cbClsExtra
mov dword[WNDCLASSA + 16], 0 ; cbWndExtra
mov RAX, qword[HINSTANCE]
mov qword[WNDCLASSA + 24], RAX ; hInstance
mov qword[WNDCLASSA + 32], 0 ; hIcon
mov qword[WNDCLASSA + 40], 0 ; hCursor
mov qword[WNDCLASSA + 48], 0 ; hbrBackground
mov qword[WNDCLASSA + 56], 0 ; lpszMenuName
mov qword[WNDCLASSA + 64], WindowClassName ; lpszClassName
lea RCX, WNDCLASSA
sub rsp, 0x20 ; Shadow Space
call RegisterClassA
add rsp, 0x20 ; Shadow Space
; Create The Window
xor RCX, RCX ; dwExStyle
mov RDX, WindowClassName ; lpClassName
MOV R8, WindowName ; lpWindowName
MOV R9, 13565952 ; dwStyle
sub rsp, 96
mov qword[rsp + 20h + 56], 0 ; lpParam
mov RAX, qword[HINSTANCE] ;
mov qword[rsp + 20h + 48], RAX ; hInstance
mov qword[rsp + 20h + 40], 0 ; hMenu
mov qword[rsp + 20h + 32], 0 ; hWndParent
mov qword[rsp + 20h + 24], 1080 ; nHeight
mov qword[rsp + 20h + 16], 1920 ; nWidth
mov qword[rsp + 20h + 8], 100 ; Y
mov qword[rsp + 20h], 100 ; X
call CreateWindowExA
add rsp, 96
mov qword[HWND], RAX ; Save the window handle
; Show The Window
sub rsp, 0x20
mov RCX, qword[HWND]
mov RDX, 5
call ShowWindow
add rsp, 0x20
; Message Loop
message_loop:
sub rsp, 48
LEA RCX, [MSG]
mov RDX, qword[HWND]
mov R8, 0
mov R9, 0
mov qword[rsp + 20h], 1
call PeekMessageA
add rsp, 48
sub rsp, 32
LEA RCX, [MSG]
call TranslateMessage
LEA RCX, [MSG]
call DispatchMessageA
add rsp, 32
jmp message_loop
; Epilogue
mov rsp, rbp
pop rbp
ret
section .data
HINSTANCE dq 0
HWND dq 0
WindowClassName db 'Polar Window Class', 0
WindowName db 'Polar Window', 0
section .bss
WNDCLASSA resb 72
MSG resb 48