News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Win32 Console Addition

Started by demondoido, April 09, 2013, 01:56:04 AM

Previous topic - Next topic

demondoido

I want to do a simple addition using numbers provided by the console line, something like this:


.486
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib

.data
    msg1 BYTE "Insert a number:"
    msg2 BYTE "The sum is:"
.data?
    oHandle DWORD ?
    iHandle DWORD ?
    bufferLen DWORD ?
    buffer BYTE ?
.code
start:
    invoke GetStdHandle, -11
    mov oHandle, eax
    invoke GetStdHandle, -10
    mov iHandle, eax
    invoke WriteFile, oHandle, addr msg1, lengthof msg1, NULL, NULL
    invoke ReadFile, iHandle, addr buffer, 1, addr bufferLen, NULL
    mov al, 0h
    mov al, buffer
    mov buffer, 0h ; I need some way to clean the buffer, this way doesn't work
    invoke WriteFile, oHandle, addr msg1, lengthof msg1, NULL, NULL
    invoke ReadFile, iHandle, addr buffer, 1, addr bufferLen, NULL
    add al, buffer
    mov buffer, al
    invoke WriteFile, oHandle, addr msg2, lengthof msg2, NULL, NULL
    invoke WriteFile, oHandle, addr buffer, lengthof buffer, NULL, NULL

   invoke ExitProcess, 0
end start


Can someone give me a light?
Something like the principle of this code...

Thanks..

dedndave

well - you need different buffers for the 2 values

this
    mov al, 0h
    mov al, buffer
    mov buffer, 0h

and this
    add al, buffer
    mov buffer, al

make no sense

the value in EAX (AX, AL) is not preserved across API calls

so - you put the first number in buffer1
put the second number in buffer2
then, convert them from ASCII decimal to binary
then, add them together
then, convert the result from binary to ASCII decimal and display it

demondoido

Hmmm... Sorry for my stupidity,  but I have another problem, when I do this:


invoke WriteFile, oHandle, addr msg1, lengthof msg1, NULL, NULL
    invoke ReadFile, iHandle, addr buffer1, 1, addr bufferLen1, NULL
    invoke WriteFile, oHandle, addr msg1, lengthof msg1, NULL, NULL
invoke ReadFile, iHandle, addr buffer2, 1, addr bufferLen2, NULL


The first number is repeated in the second request, then program ends...... I think there's a problem with keyboard buffer, right?  How can I solve this?

dedndave

that problem is caused by using NULL for lpNumberOfBytesWritten
give it a valid pointer to a dword variable, and it should work
QuoteThis parameter can be NULL only when the lpOverlapped parameter is not NULL.

you've done quite well, really   :t
but, let's step back a little and look at some other things
these are not critical problems, but may help you in the future

.486
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib

all of that stuff can be replaced with a single line
        include    \masm32\include\masm32rt.inc
that is a plain text file that you can browse with NotePad to see what's inside

    invoke GetStdHandle, -11
    mov oHandle, eax
    invoke GetStdHandle, -10
    mov iHandle, eax

the windows.inc file defines hundreds of windows constants that will make your code easier to read
STD_INPUT_HANDLE                     equ -10
STD_OUTPUT_HANDLE                    equ -11

so, if i were to write it, it might look like this...
        INVOKE  GetStdHandle,STD_INPUT_HANDLE
        mov     hStdInp,eax
        INVOKE  GetStdHandle,STD_OUTPUT_HANDLE
        mov     hStdOut,eax


the "lengthof" and "sizeof" operators are a little different
in the case of bytes, they yield the same thing
but, if i were to get the "lengthof dwValue" of a dword variable, it would yield 1
if i were to get the "sizeof dwValue" of a dword variable, it would yield 4
lengthof gives you the number of elements
sizeof gives you the number of bytes
it makes little difference in this case, but if i were to modify the program for UNICODE, i'd have a bug
the WriteFile function wants the "number of bytes", not the "number of characters"
in that case, "sizeof" would be more appropriate

demondoido

Oh thanks, really, I don't know how to thank you... Precious tips! But still with the same problem, but now the first number is not repeated in the second request... The program only shows the second request and ends, doesn't wait the input!
The code is:


include  \masm32\include\masm32rt.inc

.data
    msg1 BYTE "Insert a number:"
    msg2 BYTE "The sum is:"
.data?
    oHandle DWORD ?
    iHandle DWORD ?
    writeLen1 DWORD ?
    writeLen2 DWORD ?
    bufferLen1 DWORD ?
    bufferLen2 DWORD ?
    buffer1 BYTE ?
    buffer2 BYTE ?
.code
start:
    invoke GetStdHandle, STD_OUTPUT_HANDLE 
    mov oHandle, eax
    invoke GetStdHandle, STD_INPUT_HANDLE 
    mov iHandle, eax
    invoke WriteConsole, oHandle, addr msg1, lengthof msg1, addr writeLen1, NULL
    invoke ReadConsole, iHandle, addr buffer1, 2, addr bufferLen1, NULL
    invoke WriteConsole, oHandle, addr msg1, lengthof msg1, addr writeLen2, NULL
    invoke ReadConsole, iHandle, addr buffer2, 2, addr bufferLen2, NULL

   invoke ExitProcess, 0
end start


Sorry for being annoying, I really want to learn Assembly from the basic to the advanced (maybe even create an OS hohoho  :lol:)

dedndave

ok - that time, you are reading 2 bytes into 1 byte buffers

demondoido

ohh...  :redface: not resolved switch for reading one byte...

dedndave

well - i didn't notice that you were using WriteConsole/ReadConsole
i would typically use WriteFile/ReadFile
give me a minute to play with it....

demondoido

Both API functions are producing the same problem... Doesn't matter if I use WriteFile/ReadFile or WriteConsole/ReadConsole,  in both cases the second Read function is ignored!

dedndave

yah - i understand what's happening - sort of - lol

the buffer is 1 char long
but, when you enter a value, you are entering a char, plus the carriage return   :P

another problem arises because the ReadFile function does not limit the number of characters entered
so - if you have a buffer of 2 chars and enter 10, those extra characters are still in the buffer
the next time you call ReadFile, poof - those extra characters are sitting there, waiting - lol

you can set up the standard input device so that doesn't happen
invoke SetConsoleMode,hStdInp,ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT or ENABLE_PROCESSED_INPUT
once at the beginning of the program

then use ReadFile and WriteFile in preference to ReadConsole and WriteConsole

jj2007

Quote from: dedndave on April 09, 2013, 05:43:57 AM
but, when you enter a value, you are entering a char, plus the carriage return   :P

Yep!

    buffer1 BYTE 100 dup(?)
    buffer2 BYTE 100 dup(?)
.code
start:
    invoke GetStdHandle, STD_OUTPUT_HANDLE 
    mov oHandle, eax
    invoke GetStdHandle, STD_INPUT_HANDLE 
    mov iHandle, eax
    invoke WriteConsole, oHandle, addr msg1, lengthof msg1, addr writeLen1, NULL
    invoke ReadConsole, iHandle, addr buffer1, 100, addr bufferLen1, NULL
    invoke WriteConsole, oHandle, addr msg1, lengthof msg1, addr writeLen2, NULL
    invoke ReadConsole, iHandle, addr buffer2, 100, addr bufferLen2, NULL

dedndave

also - make the buffer n+1 length
in other words, pass the (buffer length-1) to the function

dedndave

i did the above and it still acts strangely   :lol:
let me fix it.....

demondoido

Very strange, with the way of jj2007 works well, but... 100 bytes buffer to do this?

dedndave

yah - you should be able to use a smaller buffer and specify it's length
i must be doing something wrong, here

here is the test program i am using
in this case, i added 3 extra bytes to the buffer and passed a length 3 less

it acts as though the input buffer is not being emptied by ReadFile
;###############################################################################################

        .XCREF
        .NoList
        INCLUDE    \Masm32\Include\Masm32rt.inc
        .List

;###############################################################################################

        .DATA

msg1       BYTE "Insert a number: "
msg2       BYTE "The sum is: "
CrLf       BYTE 13,10

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

        .DATA?

oHandle    DWORD ?
iHandle    DWORD ?
RdWrBytes  DWORD ?
buffer1    BYTE 4 dup(?)
buffer2    BYTE 4 dup(?)

;###############################################################################################

        .CODE

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

_main   PROC

    invoke GetStdHandle, STD_OUTPUT_HANDLE 
    mov oHandle, eax
    invoke GetStdHandle, STD_INPUT_HANDLE 
    mov iHandle, eax
    invoke SetConsoleMode,iHandle,ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT or ENABLE_PROCESSED_INPUT

    invoke WriteFile, oHandle, addr msg1, sizeof msg1, addr RdWrBytes, NULL
    invoke ReadFile, iHandle, addr buffer1, sizeof buffer1-3, addr RdWrBytes, NULL

    invoke WriteFile, oHandle, addr msg1, sizeof msg1, addr RdWrBytes, NULL
    invoke ReadFile, iHandle, addr buffer2, sizeof buffer2-3, addr RdWrBytes, NULL

    invoke WriteFile, oHandle, addr buffer1, sizeof buffer1-3, addr RdWrBytes, NULL
    invoke WriteFile, oHandle, addr CrLf, sizeof CrLf, addr RdWrBytes, NULL
    invoke WriteFile, oHandle, addr buffer2, sizeof buffer2-3, addr RdWrBytes, NULL
    invoke WriteFile, oHandle, addr CrLf, sizeof CrLf, addr RdWrBytes, NULL

    INVOKE  ExitProcess,0

_main   ENDP

;###############################################################################################

        END     _main