Winapi 在堆栈上传递的参数不是';t被传递给被调用函数
我正在使用nasm、cl.exe和win32 API调用为windows编写x86-64程序集的游戏。我的应用程序成功地创建了一个窗口,但它没有正确的大小和位置(它很高,但水平方向很窄) 下面是我的代码部分,它创建窗口并在使用Winapi 在堆栈上传递的参数不是';t被传递给被调用函数,winapi,assembly,x86-64,calling-convention,Winapi,Assembly,X86 64,Calling Convention,我正在使用nasm、cl.exe和win32 API调用为windows编写x86-64程序集的游戏。我的应用程序成功地创建了一个窗口,但它没有正确的大小和位置(它很高,但水平方向很窄) 下面是我的代码部分,它创建窗口并在使用GetModuleHandleA(NULL)获得HINSTANCE并使用RegisterClassA注册窗口类后显示它 ; Create The Window mov RCX, 0 ; dwExStyle mov RDX, WindowClass
GetModuleHandleA(NULL)
获得HINSTANCE
并使用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
我在binary ninja中查看了它,并向我展示了只有前6个参数被传递到CreateWindowExA
。我已经看过了,但没发现有什么不对劲
根据它,参数是这样传递的:
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
我的代码有很多问题,所以我找不到一个问题,它们都被解决了。因此,以下是我如何在评论的帮助下解决我的问题(谢谢)。我没有分配阴影空间,也没有将我放在堆栈上的参数与8字节对齐。我的汇编代码现在看起来是这样的(未优化且无异常处理):
我的代码有很多问题,所以我找不到一个问题,它们都被解决了。因此,以下是我如何在评论的帮助下解决我的问题(谢谢)。我没有分配阴影空间,也没有将我放在堆栈上的参数与8字节对齐。我的汇编代码现在看起来是这样的(未优化且无异常处理):
子rsp,48
可疑。你有12个参数,我希望是12*8=96。额外的参数应该放在堆栈上,从[rsp+32]
开始。注意:堆栈插槽为8字节,即使传递4字节整数也是如此。Jester是正确的,阴影空间是函数调用之前堆栈上的前32个字节,参数在之后。阴影空间是通常放置前4个参数的区域。被调用方可以将它们复制到那里。您还需要声明展开代码,以便异常处理可以工作。如果在开场白中调整堆栈指针,则展开代码将更容易编写,以避免必须声明收缩包装的麻烦。但为什么要汇编?性能似乎不是ANSI和UTF-16之间所有这些转换的直接目标。sub-rsp,48
是可疑的。你有12个参数,我希望是12*8=96。额外的参数应该放在堆栈上,从[rsp+32]
开始。注意:堆栈插槽为8字节,即使传递4字节整数也是如此。Jester是正确的,阴影空间是函数调用之前堆栈上的前32个字节,参数在之后。阴影空间是通常放置前4个参数的区域。被调用方可以将它们复制到那里。您还需要声明展开代码,以便异常处理可以工作。如果在开场白中调整堆栈指针,则展开代码将更容易编写,以避免必须声明收缩包装的麻烦。但为什么要汇编?性能似乎不是ANSI和UTF-16之间所有这些转换的直接目标。仍然不太正确。调用GetModuleHandleA时没有分配阴影空间,也没有声明任何展开代码。仍然不太正确。调用GetModuleHandleA时没有分配卷影空间,也没有声明任何展开代码。
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