Author Topic: Pause Before Exit.  (Read 4184 times)

afueikawa

  • Regular Member
  • *
  • Posts: 4
Pause Before Exit.
« on: September 12, 2014, 12:59:08 AM »
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.

Code: [Select]
.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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #1 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

Code: [Select]
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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #2 on: September 12, 2014, 01:57:41 AM »
Code: [Select]
        push    0
        call    ExitProcess

you can use INVOKE to call ExitProcess
Code: [Select]
        INVOKE  ExitProcess,0
there is also an "exit" macro that saves a little typing
Code: [Select]
exit0:
        inkey
        exit

afueikawa

  • Regular Member
  • *
  • Posts: 4
Re: Pause Before Exit.
« Reply #3 on: September 12, 2014, 03:25:04 AM »
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

  • Member
  • *****
  • Posts: 3515
  • Forgive your enemies, but never forget their names
Re: Pause Before Exit.
« Reply #4 on: September 12, 2014, 03:35:31 AM »
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
Get your facts first, and then you can distort them.

afueikawa

  • Regular Member
  • *
  • Posts: 4
Re: Pause Before Exit.
« Reply #5 on: September 12, 2014, 03:56:51 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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #6 on: September 12, 2014, 04:09:55 AM »
the problem lies here

Code: [Select]
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)

Code: [Select]
        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

  • Member
  • *****
  • Posts: 1704
Re: Pause Before Exit.
« Reply #7 on: September 12, 2014, 04:31:38 AM »
Hi afueikawa,

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

Code: [Select]
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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #8 on: September 12, 2014, 04:51:28 AM »
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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #9 on: September 12, 2014, 05:11:51 AM »
here is a routine that uses the msvcrt library functions to get a single key stroke
it works as a "polled" function (not blocking)

Code: [Select]
;*************************************************************************

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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #10 on: September 12, 2014, 05:14:52 AM »
this one uses the windows API function, ReadConsoleInput
it is a blocking function

Code: [Select]
;***********************************************************************************************

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

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: Pause Before Exit.
« Reply #11 on: September 12, 2014, 05:34:27 AM »
here is a little program that displays the case of each keyboard character...

afueikawa

  • Regular Member
  • *
  • Posts: 4
Re: Pause Before Exit.
« Reply #12 on: September 12, 2014, 05:54:51 AM »
Thanks guys.. Gotta keep these snippets to file.

Comes usable in the future.  8)