如何在汇编中正确调用 64 位 Windows API [英] How To Properly call 64 Bit Windows API In Assembly
问题描述
使用 NASM 和 Mingw-w64 我一直在尝试运行以下程序,该程序应该使用 Windows API 将消息打印到屏幕上.它运行,但控制台上没有显示任何内容,并导致对内存位置的无效访问(错误代码 0x3e6h).为什么会这样,我怎样才能让程序正常运行?
Using NASM and Mingw-w64 I've been trying to run the following program which is supposed to print a message to the screen using the Windows API. It runs, but nothing shows on the console and it results in an invalid access to memory location (error code 0x3e6h). Why is that, and how can I get the program to run properly?
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
推荐答案
[rsp-04h]
正在堆栈指针下方寻址,这是个坏主意.无论如何,您在那里写的任何内容都会被 call
覆盖.看起来您需要复习一下调用约定的知识.必须为寄存器中的 4 个参数分配影子空间,并且必须将更多参数放置在它们之上.
[rsp-04h]
is addressing below the stack pointer, that's a bad idea. Whatever you write there will be overwritten by the call
anyway.
Looks like you need to brush up on your knowledge of the calling convention. Shadow space for the 4 arguments in registers have to be allocated and further arguments must be placed on top of them.
另外,要写入的字节数应该是实际数字,而不是指针.
Also, the number of bytes to write should be the actual number, not a pointer.
global main
extern GetStdHandle
extern WriteFile
section .text
main:
mov rcx, 0fffffff5h
call GetStdHandle
mov rcx, rax
mov rdx, NtlpBuffer
mov r8, [NtnNBytesToWrite]
mov r9, NtlpNBytesWritten
sub rsp, 40
mov dword [rsp + 32], 00h
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
这篇关于如何在汇编中正确调用 64 位 Windows API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!