【发布时间】:2020-04-15 21:09:20
【问题描述】:
我正在尝试在 NASM 中运行一个简单的 Hello world 程序。 我想在不使用 C-Libraries 的情况下打印到控制台,直接与 WinAPI 交互。
我正在使用 Visual Studio 提供的 LINK.EXE 进行链接。
到目前为止,这是我的代码:
section .data
message: db 'Hello world!',10 ; 'Hello world!' plus a linefeed character
messageLen: db $-message ; Length of the 'Hello world!' string
global _start
extern GetStdHandle
extern WriteConsoleW
extern ExitProcess
section .text
_start:
; DWORD bytes;
mov rbp, rsp
sub rsp, byte 8
; hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
mov ecx, -11
call GetStdHandle
; WriteFile(hstdOut, message, length(message), &bytes, 0);
mov rcx, rax
mov rdx, message
mov r8, messageLen
lea r9, [rsp-4]
push 0
call WriteConsoleW
; ExitProcess(0)
mov rcx, 0
call ExitProcess
ret
我像这样组装和链接:
nasm -f win64 .\ASM.ASM
link /entry:_start /nodefaultlib /subsystem:console .\ASM.obj "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64\kernel32.lib" "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64\user32.lib"
但是,当我运行生成的 .exe 文件时,我什么也得不到。
到目前为止我尝试过的一些事情是
- 使用修饰名称(如 _GetStdHandle@4),导致链接器抱怨未解析的引用
- 未尝试打印任何内容并调用 Sleep,导致进程无限期休眠
- 以不同的返回码退出,这又一次什么也没做
我做错了什么?
编辑:固定调用约定
【问题讨论】:
-
您的代码是 x64,而不是 x86。你需要先学习 x64 调用约定
-
我已经修复了调用约定问题,但最终结果还是一样。查看问题的编辑
-
您还没有完全修复调用约定:您没有保留 32 字节的影子空间,因此您调用的函数可能会踩到您的堆栈空间。
标签: winapi assembly x86 x86-64 nasm