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
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 ...