I'm trying to get a simple Hello world program in NASM to run. I want to print to the console without using C-Libraries, interfacing directly with WinAPI.
I am using the Visual Studio provided LINK.EXE for linking.
Here's my code so far:
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
Which I assemble and link like this:
nasm -f win64 .ASM.ASM
link /entry:_start /nodefaultlib /subsystem:console .ASM.obj "C:Program Files (x86)Windows Kits10Lib10.0.18362.0umx64kernel32.lib" "C:Program Files (x86)Windows Kits10Lib10.0.18362.0umx64user32.lib"
However when I run the resulting .exe file, I get nothing.
Some things I tried so far are
- Using the decorated names (like _GetStdHandle@4), which resulted in the linker complaining about unresolved references
- Not trying to print anything and calling Sleep, which resulted in the process sleeping indefinitely
- Exiting with a different return code, which once again did nothing
What am I doing wrong?
EDIT: Fixed calling convention
See Question&Answers more detail:os