News:

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

User input help

Started by Zyth, February 25, 2010, 06:56:39 PM

Previous topic - Next topic

Zyth

Hi all.

I'm putting together one of my first assembly programs and need a little help.  Right now I'm not
concerned with the efficiency of the code (I'm still learning).  I just would like to get it to work.  :bg

Its a console program that simply prompts the user for two numbers that are then added together
and output.  Somewhere in the conversions the numbers are getting messed up and its outputting
the incorrect number as the sum.  Here's a sample run:

Enter first number:  10
Enter second number:  20

The sum is 7856 

I think it might be because the user input isn't null terminated?  I replaced the user input with hard
coded numbers as a test and it returned the correct sum:

test_string1    BYTE        "10", 0
test_string2    BYTE        "20", 0

Anyway, here's the code.  Any help would be appreciated:

.386

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

include \masm32\include\masm32rt.inc



cr          EQU         0dh
Lf          EQU         0ah

.STACK  4096

.DATA
number1         DWORD       ?
number2         DWORD       ?
string          BYTE        40 DUP (?)
prompt1         BYTE        "Enter first number:  ", 0
prompt2         BYTE        "Enter second number:  ", 0
label1          BYTE        cr, Lf, "The sum is ", 0
sum             BYTE        11 DUP (?)
endline         BYTE        cr, Lf, 0
   

.CODE

_start:
   
    cls
    INVOKE  StdOut, ADDR prompt1
    INVOKE  StdIn, ADDR string, 40
    INVOKE  atodw, ADDR string
    mov     number1, eax

    INVOKE  StdOut, ADDR prompt2
    INVOKE  StdIn, ADDR string, 40
    INVOKE  atodw, ADDR string
    mov     number2, eax

    mov     eax, number1
    add     eax, number2
    INVOKE  dwtoa, eax, ADDR sum
    INVOKE  StdOut, ADDR label1
    INVOKE  StdOut, ADDR sum
   
    INVOKE ExitProcess, 0

END _start




jj2007

atodw is not the most intelligent function. If it finds CrLf, which is included in the string when using StdIn, the 13 + 10 values will be interpreted as input... so you have to insert a nullbyte where the Cr is.

Slugsnack

look into StripLF() for that :]

jj2007

Or do it by hand...
    INVOKE  StdOut, ADDR prompt1
    mov edi, offset string
    INVOKE  StdIn, edi, 40
    mov al, 13
    or ecx, -1
    repne scasb
    mov byte ptr [edi-1], 0
    INVOKE  atodw, offset string
    mov     number1, eax

    INVOKE  StdOut, ADDR prompt2
    mov edi, offset string
    INVOKE  StdIn, edi, 40
    mov al, 13
    or ecx, -1
    repne scasb
    mov byte ptr [edi-1], 0
    INVOKE  atodw, offset string
    mov     number2, eax

Slugsnack

StripLF proc src:DWORD

    mov eax, [esp+4]
    sub eax, 1
  @@:
    add eax, 1
    cmp BYTE PTR [eax], 0
    je tlfout
    cmp BYTE PTR [eax], 13
    jne @B

    mov BYTE PTR [eax], 0
    ret 4

  tlfout:
    ret 4

StripLF endp

jj2007

What's the first ret 4 good for?

Slugsnack

Quote from: jj2007 on February 25, 2010, 09:11:36 PM
What's the first ret 4 good for?
it's completely obsolete. however that is how the StripLF function is defined in the masm32 library

MichaelW

A ret 4 is essential as StripLF is defined:

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

StripLF proc src:DWORD

    mov eax, [esp+4]
    sub eax, 1
  @@:
    add eax, 1
    cmp BYTE PTR [eax], 0
    je tlfout
    cmp BYTE PTR [eax], 13
    jne @B

    mov BYTE PTR [eax], 0
    ret 4

  tlfout:
    ret 4

StripLF endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


The first one is redundant, though.
eschew obfuscation