News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Pause Before Exit.

Started by afueikawa, September 12, 2014, 12:59:08 AM

Previous topic - Next topic

afueikawa

Hello everyone. My first post on the forum.

Created a simple input/output program using MASM32 Editor (Quick Editor 4.0).
What the program does is that, it will ask for a name, then display a message with that name.

The problem is that, the console should pause for a moment and wait for a key to be pressed before exiting,
similar to the getch() or system("pause") in C++. And where Am I going to insert that code.

Here's  my code.


.386
.model flat, stdcall
option casemap:none

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib

.data
       msg1 db "What is your name? ", 0
       msg2 db "Hello ",0

.data?
       buffer db 100 dup(?)   ; reserve 100 bytes for input storage

.code
start:
       push offset msg1        ; put in to stack the effective add of msg1
       call StdOut                  ; call console display API

       push 100                    ; set the maximum input character
       push offset buffer       ; put in to stack the effective add of input storage
       call StdIn                    ; call console input API

       push offset msg2       ; put in to stack the effective add of msg2
       call StdOut                 ; call console display API

       push offset buffer      ; put in to stack the effective add of input storage
       call StdOut                 ; call console display API

exit:
       push 0
       call ExitProcess
end start


dedndave

if you open the console window first, then run the program by typing the name, it will work
but, many of us prefer to click on the exe file in explorer to run it

exit0:
        inkey
        push    0
        call    ExitProcess


"inkey" is a masm32 macro
it displays "Press Any Key To Continue..." and waits for a keypress

the name "exit" is already used for a macro name, so use a different name for the label, like "exit0"

dedndave

        push    0
        call    ExitProcess


you can use INVOKE to call ExitProcess
        INVOKE  ExitProcess,0

there is also an "exit" macro that saves a little typing
exit0:
        inkey
        exit

afueikawa

Tried your suggestions but fro some reason, the console still closes after I enter a name.

I also received an error when using the inkey.

Gunther

Hi afueikawa,

could you post the entire code and build filers as ZIP package, please? We can better help with that informations. And welcome to the forum.

Gunther
You have to know the facts before you can distort them.

afueikawa

Quote from: dedndave on September 12, 2014, 01:55:52 AM
if you open the console window first, then run the program by typing the name, it will work
but, many of us prefer to click on the exe file in explorer to run it

Wow, funny How i missed that part.

It works fine. Thanks guys.!! 8)

dedndave

the problem lies here

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib


the msvcrt include and lib are also required for many macros

but, we generally use the "\masm32\include\masm32rt.inc" file
it adds most of the commonly used incs/libs, as well as the preface stuff (processor, model, casemap)

        include \masm32\include\masm32rt.inc

.data
       msg1 db "What is your name? ", 0
       msg2 db "Hello ",0

.data?
       buffer db 100 dup(?)   ; reserve 100 bytes for input storage

.code
start:
       push offset msg1        ; put in to stack the effective add of msg1
       call StdOut                  ; call console display API

       push 100                    ; set the maximum input character
       push offset buffer       ; put in to stack the effective add of input storage
       call StdIn                    ; call console input API

       push offset msg2       ; put in to stack the effective add of msg2
       call StdOut                 ; call console display API

       push offset buffer      ; put in to stack the effective add of input storage
       call StdOut                 ; call console display API

exit0:
       inkey
       push 0
       call ExitProcess

end start

Vortex

Hi afueikawa,

You can use the _getch function exported by msvcrt.dll :


include     \masm32\include\masm32rt.inc

.data

str1        db 'Press any key to exit.',13,10,0

.code

start:

    invoke  crt_printf,ADDR str1

    invoke  crt__getch

    invoke  ExitProcess,0

END start

dedndave

you can also look at source code for the macros

\masm32\macros\macros.asm

and the masm32 functions

\masm32\m32lib\*.asm

you can see that "inkey" uses getch, as Vortex suggested, and it also uses kbhit from msvcrt

dedndave

here is a routine that uses the msvcrt library functions to get a single key stroke
it works as a "polled" function (not blocking)

;*************************************************************************

InKyb   PROC

;Polled Keyboard Input - DednDave 8, 2010
;
;This function returns a keystroke in EAX if there is one in the buffer.
;If the buffer is empty, the function returns immediately.
;
;If the keyboard buffer is empty, AH = 0, AL = 0, ZF = 1.
;If the stroke is a regular key, AH = 0, AL = key char, ZF = 0.
;If the stroke is an extended key, AH = extended key, AL = E0h, ZF = 0.
;If the stroke is a function key, AH = function key, AL = 0, ZF = 0.
;
;ECX, EDX are not preserved.

        call    crt__kbhit
        or      eax,eax
        jz      InKyb1

        call    crt__getch
        and     eax,0FFh
        jz      InKyb0

        cmp     al,0E0h
        jnz     InKyb1

InKyb0: push    eax
        call    crt__getch
        pop     edx
        shl     eax,8
        or      eax,edx

InKyb1: retn

InKyb   ENDP

;*************************************************************************

dedndave

this one uses the windows API function, ReadConsoleInput
it is a blocking function

;***********************************************************************************************

AnyKey  PROC

;Wait for Any Console Key Press - DednDave
;version 1, 12-2011
;version 2, 2-2013
;
;  This function returns when any console key is pressed (bKeyDown = 1).
;A possible drawback is that all input event records are removed from
;the console input queue until a key is pressed. In many cases, this is
;not an issue. The virtual key code, virtual scan code, TCHAR character,
;and control key state values are returned in registers.

;Call With: Nothing
;
;  Returns: EAX = TCHAR character (high word of EAX = 0)
;           ECX = control key state flags
;               Bit   Name                Meaning
;                0    RIGHT_ALT_PRESSED   Right ALT key is pressed
;                1    LEFT_ALT_PRESSED    Left ALT key is pressed
;                2    RIGHT_CTRL_PRESSED  Right CTRL key is pressed
;                3    LEFT_CTRL_PRESSED   Left CTRL key is pressed
;                4    SHIFT_PRESSED       SHIFT key is pressed
;                5    NUMLOCK_ON          NUM LOCK light is on
;                6    SCROLLLOCK_ON       SCROLL LOCK light is on
;                7    CAPSLOCK_ON         CAPS LOCK light is on
;                8    ENHANCED_KEY        Key is enhanced
;           EDX:
;           low word (DX) = virtual key code
;               high word = virtual scan code
;
;           all other registers are preserved

;-------------------------------------------------

    LOCAL   ir          :INPUT_RECORD
    LOCAL   uRecCnt     :UINT
    LOCAL   hStdInp     :HANDLE

;-------------------------------------------------

    INVOKE  GetStdHandle,STD_INPUT_HANDLE
    mov     hStdInp,eax
    .repeat
        INVOKE  ReadConsoleInput,hStdInp,addr ir,1,addr uRecCnt
        movzx   ecx,word ptr ir.EventType
        mov     edx,dword ptr ir.KeyEvent.wVirtualKeyCode
    .until (ecx==KEY_EVENT) && (ecx==ir.KeyEvent.bKeyDown) && (dx!=VK_SHIFT) && (dx!=VK_CONTROL) && (dx!=VK_MENU)
    movzx   eax,word ptr ir.KeyEvent.UnicodeChar
    mov     ecx,ir.KeyEvent.dwControlKeyState
    ret

AnyKey  ENDP

;***********************************************************************************************

dedndave

here is a little program that displays the case of each keyboard character...

afueikawa

Thanks guys.. Gotta keep these snippets to file.

Comes usable in the future.  8)