Why Masm32 only give 1 to 100 result for add and subtraction operation and beyond that I got wrong answer?

217 views Asked by At

I am new to assembly language. I make this code just now and run it with no errors so far, except It will only give a result from 1 - 100, here's my code.

This is a simple math operation which is addition and subtraction. I tried analyzing the code like maybe in num1 db 10 dup (?) I tried changing 10 to 100 but still it wont work. Did I miss something?

.386
.model flat, stdcall
option casemap :none
include \masm32\include\masm32rt.inc

.data
    msgEC db "Choose Operation", 00ah, 0
    msgAdd db "Addition 1", 00ah, 0
    msgSub db "Subtraction 2", 00ah, 0
    msgEx db "Exit 3", 00ah, 0
    msg db "Addition", 00ah, 0
    msgSub2 db "Subtraction", 00ah, 0
    msg1 db "Enter 1st Number:", 00ah, 0
    msg2 db "Enter 2nd Number:", 00ah, 0
    msg3 db "Sum is:", 00ah, 0
    msgdf db "Diff is:", 00ah, 0
    endl db 00ah, 0
    msg4 db "Try Again[1/0]:", 0
.data?

    num1 db 10 dup (?)
    num2 db 10 dup (?)
    res sdword ?
    choice db 10 dup (?)
    choice2 db 10 dup (?)

.code
start:
    invoke StdOut, addr msgAdd
    invoke StdOut, addr msgSub 
    invoke StdOut, addr msgEx
    invoke StdOut, addr msgEC
    invoke StdIn, addr choice2, 10
    mov[choice2 + eax-3], 0
    invoke StripLF, addr choice2
    invoke atodw, addr choice2

    .if eax == 1
    jmp _addition
    .elseif eax == 2
    jmp _subtraction
    .elseif eax == 3 || eax > 3
    jmp _exit
    .endif


_addition:

    invoke ClearScreen
    invoke StdOut, addr msg
    invoke StdOut, addr msg1
    invoke StdIn, addr num1, 10
    mov[num1 + eax-3], 0
    invoke StripLF, addr num1
    invoke atodw, addr num1
    mov ebx, eax

    invoke StdOut, addr msg2
    invoke StdIn, addr num2, 10
    mov[num2 + eax-3], 0
    invoke StripLF, addr num2
    invoke atodw, addr num2
    add ebx, eax   

    invoke dwtoa, ebx, addr res
    invoke StdOut, addr msg3
    invoke StdOut, addr res
    invoke StdOut, addr endl

    invoke StdOut, addr msg4
    invoke StdIn, addr choice, 10
    mov[choice + eax-3], 0
    invoke StripLF, addr choice
    invoke atodw, addr choice

    .if eax == 1
    jmp _addition
    .else
    .endif

_subtraction:

    invoke ClearScreen
    invoke StdOut, addr msgSub2
    invoke StdOut, addr msg1
    invoke StdIn, addr num1, 100
    mov[num1 + eax-3], 0
    invoke StripLF, addr num1
    invoke atodw, addr num1
    mov ebx, eax

    invoke StdOut, addr msg2
    invoke StdIn, addr num2, 100
    mov[num2 + eax-3], 0
    invoke StripLF, addr num2
    invoke atodw, addr num2
    sub ebx, eax   

    invoke dwtoa, ebx, addr res
    invoke StdOut, addr msgdf
    invoke StdOut, addr res
    invoke StdOut, addr endl

    invoke StdOut, addr msg4
    invoke StdIn, addr choice, 10
    mov[choice + eax-3], 0
    invoke StripLF, addr choice
    invoke atodw, addr choice

    .if eax == 1
    jmp _subtraction
    .else 
    .endif

_exit:

invoke ExitProcess, 0

end start

Edit: Example Out put is if I add 100 + 5 it shows a wrong result which is 5 but If I add lower number like 90 + 5 it output a right result 95.

1

There are 1 answers

1
Michael On BEST ANSWER

All of these operations in your code are incorrect:

mov[num1 + eax-3], 0

StdIn returns the number of characters read, excluding the NUL terminator. So if you entered 100, eax will be 3, so you'll set the very first byte to 0, thereby making num1 an empty string. Even worse, if you entered a one digit or two digit number you'll be writing outside of num1 because eax-3 will be negative.

Fortunately StdIn will both strip CRLF and NUL-terminate the string for you. So you can simply remove all of those mov[foo + eax-3], 0 instructions, as well as the invoke StripLF, addr foo calls.