Search code examples
winapiassemblyx86crashnasm

Nasm ReadConsoleInput


I'm currently working on a simple I/O console application compiled from nasm, but even though it compiles and links, it crashes when I run it. Here's the code:

STD_OUTPUT_HANDLE   equ -11
STD_INPUT_HANDLE    equ -10
NULL                equ 0

global start
extern ExitProcess, GetStdHandle, WriteConsoleA, ReadConsoleInputA

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg
consoleInHandle     dd 1

section .bss
buffer              resd 2
buffer2             resb 32

section .text
start:

push    STD_OUTPUT_HANDLE
call    GetStdHandle

push    NULL
push    buffer
push    msg.len
push    msg
push    eax
call    WriteConsoleA

read:

push STD_INPUT_HANDLE
call GetStdHandle
mov [consoleInHandle],eax
push NULL
push 1
push buffer2
push dword [consoleInHandle]
call ReadConsoleInputA

exit:

push    NULL
call    ExitProcess

Any clues? I'm running a 64 bit windows 10 machine by the way and I'm using Nasm for compilation and GoLink for linking


Solution

  • I'm assuming that you are targeting 32-bit Windows executables. You call ReadConsoleInputA, although it may be simpler to call ReadConsoleA if you are just interested in the characters entered from the keyboard. The title for your question says ReadConsole Input (a space between the two that puzzled me). Your code was:

    push STD_INPUT_HANDLE
    call GetStdHandle
    mov [consoleInHandle],eax
    push NULL
    push 1
    push buffer2
    push dword [consoleInHandle]
    call ReadConsoleInputA
    

    ReadConsoleA is similar in nature but handles just keyboard data. The code could look like this:

    push STD_INPUT_HANDLE
    call GetStdHandle
    mov [consoleInHandle],eax
    push NULL
    push buffer    ; Pointer to a DWORD for number of characters read to be returned
    push 1
    push buffer2
    push dword [consoleInHandle]
    call ReadConsoleA
    

    Although ReadConsoleInputA reads character data from the console, it handles a multitude of other events (including mouse, menu, focus, and keyboard) that you have to properly process (or ignore).

    I'm assuming it is being built with commands to generate 32-bit executables like this:

    nasm -f win32 test.asm -o test.obj    
    GoLink.exe  /console test.obj kernel32.dll
    

    If you want to target 64-bit executables, then all of your code will have to change since the 64-bit calling convention passes many parameters in registers instead of on the stack.