如何在程序集中正确调用64位Windows API

问题描述 投票:0回答:1

使用 NASM 和 Mingw-w64 我一直在尝试运行以下程序,该程序应该使用 Windows API 将消息打印到屏幕上。它运行,但控制台上没有任何显示,并且导致对内存位置的访问无效(错误代码 0x3e6h)。为什么会这样,怎样才能让程序正常运行?

global main
extern ExitProcess
extern GetStdHandle
extern WriteFile

section .text
main:
    mov     rcx,                  0fffffff5h
    call    GetStdHandle

    mov     rcx,                  rax
    mov     rdx,                  NtlpBuffer
    mov     r8,                   NtnNBytesToWrite
    mov     r9,                   NtlpNBytesWritten
    mov     dword [rsp - 04h],    00h
    call    WriteFile
ExitProgram:
    mov     rcx,                  00h
    call    ExitProcess

section .data
NtlpBuffer:        db    'Hello, World!', 00h
NtnNBytesToWrite:  dd    0eh

section .bss
NtlpNBytesWritten: resd  01h

编译者

nasm -f win64 test.asm
gcc -s -o test.exe test.obj
windows assembly 64-bit nasm
1个回答
6
投票

[rsp-04h]
是在堆栈指针下方寻址,这是一个坏主意。不管你在那里写什么,无论如何都会被
call
覆盖。 看来您需要温习一下调用约定的知识。必须为寄存器中的 4 个参数分配影子空间,并且必须将更多参数放置在它们之上。

另外,要写入的字节数应该是实际数字,而不是指针。

global main
extern GetStdHandle
extern WriteFile

section .text
main:
    sub     rsp, 40          ; need to reserve shadow space before the first call
    mov     ecx, -11         ; GetStdHandle takes a DWORD arg, write it as 32-bit.  This is STD_OUTPUT_HANDLE
    call    GetStdHandle

    mov     rcx, rax
    mov     rdx, NtlpBuffer         ; or better, lea rdx, [rel NtlpBuffer]
    mov     r8, [NtnNBytesToWrite]  ; or better, make it an EQU constant for mov r8d, bytes_to_write
    mov     r9, NtlpNBytesWritten   ; first 4 args in regs
    mov     dword [rsp + 32], 00h   ; fifth arg on the stack above the shadow space
    call    WriteFile
    add     rsp, 40
ExitProgram:
    xor     eax, eax
    ret

section .data
NtlpBuffer:        db    'Hello, World!', 00h
NtnNBytesToWrite:  dq    0eh

section .bss
NtlpNBytesWritten: resd  01h

参见如何将函数或标签的地址加载到寄存器中回复:使用RIP相关的LEA而不是

mov reg, imm64
将地址放入寄存器中。

字符串中尾随的

0
字节不是必需的;
WriteFile
采用指针 + 长度,而不是隐式长度的 C 字符串。您可能需要使用
db 'Hello...', 13,10
来包含换行符。 (DOS CR LF。)

© www.soinside.com 2019 - 2024. All rights reserved.