Author Topic: This Assembly language program exits too fast ? How to fix it ?  (Read 1364 times)

Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
This Assembly language program exits too fast ? How to fix it ?
« on: September 17, 2017, 07:44:47 AM »

Code: [Select]
; ----------------------------------------------------------------------------
; hello.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits.  It uses only plain Win32 system calls from kernel32.dll, so it
; is very instructive to study since it does not make use of a C library.
; Because system calls from kernel32.dll are used, you need to link with
; an import library.  You also have to specify the starting address yourself.
;
; Assembler: NASM
; OS: Any Win32-based OS
; Other libraries: Use gcc's import library libkernel32.a
; Assemble with "nasm -fwin32 hello.asm"
; Link with "ld -e go hello.obj -lkernel32"
; ----------------------------------------------------------------------------

        global  go
        extern  _ExitProcess@4
        extern  _GetStdHandle@4
        extern  _WriteConsoleA@20

        section .data
msg:    db      'Hello, World', 10
handle: db      0
written:
        db      0

        section .text
go:
        ; handle = GetStdHandle(-11)
        push    dword -11
        call    _GetStdHandle@4
        mov     [handle], eax

        ; WriteConsole(handle, &msg[0], 13, &written, 0)
        push    dword 0
        push    written
        push    dword 13
        push    msg
        push    dword [handle]
        call    _WriteConsoleA@20

        ; ExitProcess(0)
        push    dword 0
        call    _ExitProcess@4


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2358
  • Country: us
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #1 on: September 17, 2017, 09:09:37 AM »
Excellent!

I imagine what you want to do is to wait for a keypress. "ReadConsole" ought to do it. You'll have to "GetStdHandle" again with -10. I don't know where they got -11 for stdout and -10 for stdin, but that's how they do it.

Now I've got a minor nit to pick with your example program.
Code: [Select]
        section .data
; this is a "list of bytes"
msg:    db      'Hello, World', 10

; but "handle" and "written" need to be bigger
handle: dd      0
written:
        dd      0
These things want to be a "dword". "dw" might sound like "dword", but it's "declare word", 16 bits. For a "handle" or bytes "written", we need 32 bits, 4 bytes, or "declare dword" - "dd". When you "mov [handle], eax" you move 32 bits, and if you only reserve one byte, it'll scribble all over the next 3 bytes. That won't do any harm in this simple program, but try to pay attention to your data sizes or you'll eventually make a bug that you will notice!

Best,
Frank


Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #2 on: September 17, 2017, 11:10:54 AM »
Thanks for the reply Frank

I understand a lot of things you said , but there are lot of things i don't understand .But its OK , i will learn it slowly .

How many lines of code should be added to make it stop escaping that fast ?

I wish i could make this one program work properly and study it for the rest of my life , because i am really new to Assembly language .I only started learning this seriously like 2 days ago .

Can you help me add those lines in that code somehow ?

Because i don't know how else to continue studying this .

Maybe if i can get this example code working properly i can google the rest of the code and learn a lot more .

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2358
  • Country: us
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #3 on: September 17, 2017, 12:08:15 PM »
Over on Stack Overflow they're telling you (I assume that's you) to run it in a Window that will stay open. That's probably easier. I'll try this. I haven't run Windows since Win98 was current so this is completely untested code! Ir may give you more trouble than it's worth...
Code: [Select]
; ----------------------------------------------------------------------------
; hello.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits.  It uses only plain Win32 system calls from kernel32.dll, so it
; is very instructive to study since it does not make use of a C library.
; Because system calls from kernel32.dll are used, you need to link with
; an import library.  You also have to specify the starting address yourself.
;
; Assembler: NASM
; OS: Any Win32-based OS
; Other libraries: Use gcc's import library libkernel32.a
; Assemble with "nasm -fwin32 hello.asm"
; Link with "ld -e go hello.obj -lkernel32"
; ----------------------------------------------------------------------------

        global  go
        extern  _ExitProcess@4
        extern  _GetStdHandle@4
        extern  _WriteConsoleA@20
        extern  _ReadConsole@20

        section .data
msg:    db      'Hello, World', 10
handle:         dd      0
read_handle dd 0
written:        db      0

        section .text
go:
        ; handle = GetStdHandle(-11)
        push    dword -11
        call    _GetStdHandle@4
        mov     [handle], eax

        push -10  ; stdin
        call _GetStdHandle@4
        mov [read_handle], eax

        ; WriteConsole(handle, &msg[0], 13, &written, 0)
        push    dword 0
        push    written
        push    dword 13
        push    msg
        push    dword [handle]
        call    _WriteConsoleA@20

        push eax
        mov eax, esp ; buffer for char?
        push 0
        push written ; reuse this?
        push 1 ; characters to read?
        push eax
        push dword [read_handle]
        call ReadConsole
        pop eax ; character read in al?

        ; ExitProcess(0)
        push    dword 0
        call    _ExitProcess@4

If this works at all, it may require you to hit "Enter", not just  any key. I may be able to show you how to GetConsoleMode, "and" it with 11111001b, and SetConsoleMode so it will accept any key. This is enough untested code for now! I should know better!

Best,
Frank


Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #4 on: September 17, 2017, 02:23:39 PM »
First of all please excuse my English .It is not my native language .I am from India .

Yes that is me .That looks a bit like a not so professional way of doing it .I am mostly trying to learn the code behind it .
I am interested in the code that would Fix it , like you mentioned in few places .

In that way i can try to see the code behind it and try to learn from it .





Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #5 on: September 17, 2017, 02:37:34 PM »
Try "_ReadConsoleA@20"

The same way you call other kernel32.dll API like _WriteConsoleA@xx


Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #6 on: September 17, 2017, 02:58:10 PM »
My advice is to avoid any use of package like SASM because you'll find it difficult to seek help from the NASM's "mainstream" (forums, examples, tutorials etc). Just like Frank, I'm not familiar with "CMAIN" either. SASM is a good editor though but may not be suitable for ASM beginners due to its unconventional abstractions. For Windows starter, it is enough to have the NASM, a text editor like Notepad and GCC as the linker.

Here's one thread full of NASM examples and library where you can use and learn from.





Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #7 on: September 17, 2017, 03:37:35 PM »
@dreamCoder
Thanks for the reply

Few doubts

Is it

call  _ReadConsole@20
Quote
(.text+0x47): undefined reference to `ReadConsole@20'

or
call  _ReadConsoleA@20
Quote
error: symbol `_ReadConsoleA@20' undefined


?

Both are giving me errors .


I might move away from SASM if i cant get this program to work .

After i make this work somehow , i like to inspect every line of code and want to learn what everything does in the program .This looks like such a program where you can look in the code and learn a lot of  basics .




Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #8 on: September 17, 2017, 03:44:28 PM »
I think there was a little error in Frank's Code

Code: [Select]
; ----------------------------------------------------------------------------
; hello.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits.  It uses only plain Win32 system calls from kernel32.dll, so it
; is very instructive to study since it does not make use of a C library.
; Because system calls from kernel32.dll are used, you need to link with
; an import library.  You also have to specify the starting address yourself.
;
; Assembler: NASM
; OS: Any Win32-based OS
; Other libraries: Use gcc's import library libkernel32.a
; Assemble with "nasm -fwin32 hello.asm"
; Link with "ld -e go hello.obj -lkernel32"
; ----------------------------------------------------------------------------

        global  go
        extern  _ExitProcess@4
        extern  _GetStdHandle@4
        extern  _WriteConsoleA@20
        extern  _ReadConsole@20

        section .data
msg:    db      'Hello, World', 10
handle:         dd      0
read_handle dd 0
written:        db      0

        section .text
go:
        ; handle = GetStdHandle(-11)
        push    dword -11
        call    _GetStdHandle@4
        mov     [handle], eax

        push -10  ; stdin
        call _GetStdHandle@4
        mov [read_handle], eax

        ; WriteConsole(handle, &msg[0], 13, &written, 0)
        push    dword 0
        push    written
        push    dword 13
        push    msg
        push    dword [handle]
        call    _WriteConsoleA@20

        push eax
        mov eax, esp ; buffer for char?
        push 0
        push written ; reuse this?
        push 1 ; characters to read?
        push eax
        push dword [read_handle]
        call ReadConsole
        pop eax ; character read in al?

        ; ExitProcess(0)
        push    dword 0
        call    _ExitProcess@4

The error fixed Code

Code: [Select]
%include "io.inc"

section .text
global CMAIN
CMAIN:
    mov ebp, esp; for correct debugging
  ; ----------------------------------------------------------------------------
; hello.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits.  It uses only plain Win32 system calls from kernel32.dll, so it
; is very instructive to study since it does not make use of a C library.
; Because system calls from kernel32.dll are used, you need to link with
; an import library.  You also have to specify the starting address yourself.
;
; Assembler: NASM
; OS: Any Win32-based OS
; Other libraries: Use gcc's import library libkernel32.a
; Assemble with "nasm -fwin32 hello.asm"
; Link with "ld -e go hello.obj -lkernel32"
; ----------------------------------------------------------------------------

        global  go
        extern  _ExitProcess@4
        extern  _GetStdHandle@4
        extern  _WriteConsoleA@20
        extern  _ReadConsoleA@20

        section .data
msg:    db      'Hello, World', 10
handle:         dd      0
read_handle dd 0
written:        db      0

        section .text
go:
        ; handle = GetStdHandle(-11)
        push    dword -11
        call    _GetStdHandle@4
        mov     [handle], eax

        push -10  ; stdin
        call _GetStdHandle@4
        mov [read_handle], eax

        ; WriteConsole(handle, &msg[0], 13, &written, 0)
        push    dword 0
        push    written
        push    dword 13
        push    msg
        push    dword [handle]
        call    _WriteConsoleA@20

        push eax
        mov eax, esp ; buffer for char?
        push 0
        push written ; reuse this?
        push 1 ; characters to read?
        push eax
        push dword [read_handle]
        call  _ReadConsoleA@20
        pop eax ; character read in al?

        ; ExitProcess(0)
        push    dword 0
        call    _ExitProcess@4
    xor eax, eax
    ret

Now. it is possible to Assemble the program . But same issues , the output windows exits fast .


Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #9 on: September 17, 2017, 03:52:06 PM »
Wow I am so excited .It works :-)



You guys are so awesome .

And now i have a proper learning opportunity

Offline dreamCoder

  • Full Member
  • **
  • Posts: 106
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #10 on: September 17, 2017, 05:02:32 PM »
Glad you figured that out.

What's is actually happening is you're creating a pop-up console for the output, so the need to hold the pop up window is inevitable. You won't have to hold the screen if you targeted it for command-line. So for light / introductory purposes of I/O services, I recommend using "msvcrt.dll" instead of "kernel32.dll". You get to use useful APIs like printf, getchar, scanf, exit etc. Kernel services are a bit overkill, IMHO.

Good luck and keep practicing.

 

Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: This Assembly language program exits too fast ? How to fix it ?
« Reply #11 on: September 17, 2017, 05:39:35 PM »
@dreamCoder

Thanks a lot for all those valuable information's
Now i know where to start at least .
This is the second time i am trying to learn Assembly Language , First time it was back in 2010 .Could not make much progress .And i was stuck with a lot of Linux books .

But this is a win :-)