Winapi 在堆栈上传递的参数不是';t被传递给被调用函数

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

我正在使用nasm、cl.exe和win32 API调用为windows编写x86-64程序集的游戏。我的应用程序成功地创建了一个窗口,但它没有正确的大小和位置(它很高,但水平方向很窄)

下面是我的代码部分,它创建窗口并在使用
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