Search code examples
winapigccassemblynasmkernel32

Win32 Assembly - WriteFile() to console don't show output


I'm now programming some Windows native assembly, using NASM 2.12.01 and GCC 4.8.1 as a linker.

However, this simple HelloWorld program compiles & links without any complaints, but doesn't output anything to console screen.

It seems that GetStdHandle doesn't return a valid handle to a current console, so the output doesn't get shown up.

But problem might be some other.

Code:

; Name:     hello.asm
; Assemble: nasm.exe -fwin32 hello.asm
; Link:     gcc -mwindows -o hello hello.obj -lkernel32 -lmsvcrt
; Run:      a.exe

BITS 32
extern _GetStdHandle@4
extern _WriteFile@20
extern _ExitProcess@4
extern __getch
extern _puts

SECTION .data
    str:    db `Hello world!\n`         ; C-like strings in NASM with backticks
    strlen  equ $-str
    pause:  db "Do you know where the ANY key is? :-)",0

SECTION .text
GLOBAL _main
_main:
; Stack frame for NumberOfBytesWritten
push ebp
sub esp, 4

; http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231.aspx
; HANDLE WINAPI GetStdHandle(
;   _In_  DWORD nStdHandle
; );
push -11
call _GetStdHandle@4

; http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747.aspx
; BOOL WINAPI WriteFile(
;   _In_         HANDLE hFile,
;   _In_         LPCVOID lpBuffer,
;   _In_         DWORD nNumberOfBytesToWrite,
;   _Out_opt_    LPDWORD lpNumberOfBytesWritten,
;   _Inout_opt_  LPOVERLAPPED lpOverlapped
; );
push 0              ; lpOverlapped,
lea ebx, [ebp-4]    ; EBX: address of NumberOfBytesWritten
push ebx            ; lpNumberOfBytesWritten,
push strlen         ; nNumberOfBytesToWrite
push str            ; lpBuffer,
push eax            ; hFile (result from GetStdHandle
call _WriteFile@20

; msvcrt.dll (C library)
push pause
call _puts          ; http://msdn.microsoft.com/library/tf52y4t1.aspx
add esp, 4
call __getch        ; http://msdn.microsoft.com/library/078sfkak.aspx

; ExitProcess (0)
push 0
call _ExitProcess@4

Solution

  • In order to generate a console application, you must use the -mconsole option to GCC. See the online documentation, section 3.18.55, x86 Windows Options.

    You're using -mwindows which creates a GUI application. Windows does not create a console or set the standard handles when launching GUI applications.