News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Console I/O from windows application

Started by WillofIrony, November 05, 2007, 02:57:11 AM

Previous topic - Next topic

WillofIrony

Is it possible for a windows application to output to a console window via stdout? This would be only for debugging. If so, how would this be implimented?

Thanks in anticipation

Mark Jones

Hi Michael. It is possible to specify console window creation in the linker via "/SUBSYSTEM:CONSOLE" even in graphical applications, which will generate the console window in addition to the main window. My DWG application found here does something like this. I am unsure of any limitations or ramifications of doing this, but perhaps this may be useful. Also as a shortcut, "print xxx" can work in place of StdOut in writing to the console window where XXX is an ascii string address "print myString" or a combined macro such as 'print chr$("Hello world!",13,10)'
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

evlncrn8

or if your program is gui (and has to be) then you can do AllocConsole
and use GetStdHandle to obtain the handles needed for output/input

jj2007

Quote from: Mark Jones on November 05, 2007, 05:05:33 AM
Hi Michael. It is possible to specify console window creation in the linker via "/SUBSYSTEM:CONSOLE"  ... or a combined macro such as 'print chr$("Hello world!",13,10)'
For debugging, str$() is a very useful macro. Here is an example:

include \masm32\include\masm32rt.inc

.code

MsgText db "This is a tiny console application",13,10,0

start:
print Offset MsgText
print chr$("Eax contains ")
mov eax,123456789
print str$(eax)
invoke ExitProcess,eax
end start


It works, but watch your step: after "print", eax is no longer what it was before.

And here is the console.bat batch file used, assuming you use *.asc as extension for a console app:


REM to be placed in \MASM32 !!
@echo off

echo Assembling and running %1.asc

if exist %1.obj del %1.obj
if exist %1.exe del %1.exe

\MASM32\BIN\ML.EXE /c /coff %1.asc
if errorlevel 1 goto errasm

echo assembled OK, now linking

\MASM32\BIN\LINK.EXE /SUBSYSTEM:CONSOLE %1.obj

if errorlevel 0 goto Perfect

echo.
echo Link error
pause
goto TheEnd

:errasm
echo Assembly Error
pause
goto TheEnd

:Perfect
echo assembled and linked OK

echo -------------------------------------------- CONSOLE OUTPUT -----------------
echo.
%1.exe
if exist %1.obj del %1.obj
echo.
echo -------------------------------------------- CONSOLE OUTPUT -----------------
:TheEnd
pause
CLS

Vortex

Stdout is using internally the eax register, this is why eax is not preserved :

Quoteprint MACRO arg1:REQ,varname:VARARG      ;; display zero terminated string
        invoke StdOut,reparg(arg1)
      IFNB <varname>
        invoke StdOut,chr$(varname)
      ENDIF
    ENDM

Here is a modified version of the code above :

.386
.model flat,stdcall
option casemap:none

include consoleIO.inc

.data
message db 'Console I/O from windows application',0
capt    db 'Hello',0
MsgText db 13,10,'This is a tiny console application',13,10
        db 'Hit RETURN to terminate the application',13,10,0

.data?
buffer  db 10 dup(?)

.code

start:

    invoke  MessageBox,0,ADDR message,ADDR capt,MB_OK
    invoke  AllocConsole
    print   chr$("eax contains ")
    mov     eax,123456789
    print   str$(eax)
    print   OFFSET MsgText
    invoke  StdIn,ADDR buffer,10
    invoke  FreeConsole
    invoke  ExitProcess,eax

END start

[attachment deleted by admin]

P1

Then there is the traditional windows debug using something like DebugView to watch output.

Some conditional coding to build a debug build of your app.
g_Debug equ TRUE

ifdef g_Debug
    invoke OutputDebugString, addr szDLL_PROCESS_ATTACH
endif   


Regards,  P1   :8)

Vortex

Also, not to forget Vkim's debugging tool coming with the Masm32 package :

\masm32\vkdebug

QuoteVKDEBUG is a debugging tool for the MASM32 package. For more information
see dbgwin.hlp

redskull

also, just for completness, there's a std_err output handle as well as std_in and std_out; that way you can keep your regular output going wherever it needs to go, and just dump out errors to the screen or something equally as neat.
Strange women, lying in ponds, distributing swords, is no basis for a system of government

jj2007

Quote from: Vortex on November 05, 2007, 06:58:51 PM
Stdout is using internally the eax register, this is why eax is not preserved :

Quoteprint MACRO arg1:REQ,varname:VARARG      ;; display zero terminated string
        invoke StdOut,reparg(arg1)
      IFNB <varname>
        invoke StdOut,chr$(varname)
      ENDIF
    ENDM

I am afraid print/StdOut also uses ecx and edx, see my GetLogicalDrive code at http://www.masm32.com/board/index.php?topic=8118.msg59349#msg59349 and the test code below:

--- Output: ---
Testing all registers:
eax 6
ebx 1234567891
ecx 2088832534
edx 2089872276
esi 1234567894
edi 1234567895


include \masm32\include\masm32rt.inc

.code

start: pushad ; save all regs
print chr$("Testing all registers:")
mov eax,1234567890
inc eax
mov ebx,eax ;891
inc eax
mov ecx,eax ;892
inc eax
mov edx,eax ;893
inc eax
mov esi,eax ;894
inc eax
mov edi,eax ;895
mov eax,1234567890

print chr$(13,10,"eax ")
print str$(eax)
print chr$(13,10,"ebx ")
print str$(ebx)
print chr$(13,10,"ecx ")
print str$(ecx)
print chr$(13,10,"edx ")
print str$(edx)
print chr$(13,10,"esi ")
print str$(esi)
print chr$(13,10,"edi ")
print str$(edi)

popad
invoke ExitProcess,eax
end start

hutch--

jj,

> I am afraid print/StdOut also uses ecx and edx,

This is normal in a procedure, EAX, ECX and EDX are volatile registers where the rest MUST be preserved in a procedure.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php