assemblyx86consolemasmmasm32

x86 ASSEMBLY: Issues getting WriteConsole to work, returns 0


I'm a beginner to x86 assembly, I only just got my code to actually assemble for the first time.

I'm making a calculator program to learn and I need to print to the console to prompt the user for input. I'm not asking on how to request input, just on why my code doesn't write to the console.

Below is my code.

I've tried passing the arguments inline, from the stack, changing how I'm referencing constants. I must just be missing some information.

Also very open to documentation I may have missed or glossed over that is relevant.

Much appreciated :)

;------------------------------------------------------------------------------------------------
;  Calculator in x86
;------------------------------------------------------------------------------------------------

; Assembler Directives

.386                                            ; Full 80386 instruction set and mode
.model flat, stdcall                            ; All 32-bit and later apps are flat. Used ot include "tiny, etc"
option casemap:none                             ; Preserve the case of system identifiers but not our own, more or less

; Include files - headers and libs that we need for calling the system dlls like user32, gdi32, kernel32, etc

include D:\masm32\include\windows.inc           ; Main windows header file
include D:\masm32\include\user32.inc            ; Windows, control, etc
include D:\masm32\include\kernel32.inc          ; Handles, modules, paths, etc
include D:\masm32\include\gdi32.inc             ; Drawing into a device context (i.e. painting)

; Libs 0information needed to link our bainary to the system DLL calls

includelib D:\masm32\lib\kernel32.lib           ; Kernel32.dll
includelib D:\masm32\lib\user32.lib             ; User32.dll
includelib D:\masm32\lib\gdi32.lib              ; GDI32.dll

; Forward declarations - Our main entry point will call forward to WinMain


; Constants Data Aliases Prototypes

WriteWrapper    PROTO,                              ; PRototype declaration of WriteWrapper
            :PTR BYTE, 
            :DWORD

.DATA
    
    bytesWBuf   DWORD   ?                           ; Buffer for lpNumberOfCharsWritten

    promptWelc  DB      "Welcome to the worst assembly calculator ever!", 13, 10
    promptWelcL EQU     $-promptWelc

    exitCode    DWORD   0                          ;Init to 0. Program jumps to ExitMain if not 0 and return exitCode

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.CODE                                           ; Here is where the pgoram itself lives
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; PROTO functions [
WriteWrapper PROC, msg:PTR BYTE, msgLen:DWORD       ; WriteConsole helper. rebuilding the wheel ik

    push        STD_OUTPUT_HANDLE                   ; Getting handle and pushing it to eax
    call        GetStdHandle

    cmp         eax, -1                             ; Checking if handle is invalid
    je          b_InvalidHandle

    push        0               ;lpReserved
    push        offset bytesWBuf    ;lpNumberOfCharsWritten
    push        msgLen          ;nNumberOfCharsToWrite
    push        msg             ;*lpBuffer
    push        eax             ;hConsoleOutput
    call        WriteConsole    ;Invocation

    cmp         eax, 0                              ; Checking WriteConsole res, has been returning 0
    je          b_InvalidWriteConsoleResult

    jmp         ExitWriteWrapper

b_InvalidHandle:
    mov         exitCode, 2
    jmp         ExitWriteWrapper

b_InvalidWriteConsoleResult:
    mov         exitCode, 3
    jmp         ExitWriteWrapper
    
    
ExitWriteWrapper:
    ret

WriteWrapper ENDP


main PROC
; Initialize Out Handle

    INVOKE      WriteWrapper, offset promptWelc, promptWelcL   ;Call to WriteWrapper
    cmp         exitCode, 0                                    ;Checking exitcode for exceptions
    jne         ExitMain                                       ;Has been returning 3, which is b_InvalidConsoleResult
    jmp         ExitMain

; Exit 
ExitMain:
    push exitCode
    call ExitProcess

main ENDP

END main







Solution

  • I am a fool. I was assembling with my subsystem set to windows instead of console

    If you want this to work ensure you compile with a similar template

    ...\ml.exe /link /subsystem:console source.asm ...