assemblycalculatorx86-16dosbox

error in displaying result and executing the chosen arithmetic operation


.model small

.stack 100h



.data

    greeting db 'WELCOME TO YOUR CALCULATOR', 0Dh, 0Ah, '$'

    menu db '1 - ADDITION', 0Dh, 0Ah, '2 - SUBTRACTION', 0Dh, 0Ah, '3 - MULTIPLICATION', 0Dh, 0Ah, '4 - DIVISION', 0Dh, 0Ah, '$'

    choicePrompt db 'Enter your choice: $'

    prompt1 db 'Enter 1st Number: $'

    prompt2 db 'Enter 2nd Number: $'

    resultMsg db 'The result is: $'

    buffer db 6, ?, 5 dup(0) ; Buffer to store input (max 5 digits)

    userChoice db ?

    num1 dw 0

    num2 dw 0

    result dw 0



.code

main proc

    mov ax, @data

    mov ds, ax



    ; Print the greeting and menu

    lea dx, greeting

    mov ah, 09h

    int 21h



    lea dx, menu

    mov ah, 09h

    int 21h



    ; Print choice prompt

    lea dx, choicePrompt

    mov ah, 09h

    int 21h



    ; Read user's choice

    mov ah, 01h

    int 21h

    sub al, '0'

    mov userChoice, al

    call getch



    ; Print newline

    call printNewline



    ; Print prompt1 and read first number

    lea dx, prompt1

    mov ah, 09h

    int 21h

    call readNumber

    mov num1, ax



    call printNewline



    ; Print prompt2 and read second number

    lea dx, prompt2

    mov ah, 09h

    int 21h

    call readNumber

    mov num2, ax



    ; Perform the chosen operation

    mov ax, num1

    mov bx, num2

    cmp userChoice, 1

    je additionOp

    cmp userChoice, 2

    je subtractionOp

    cmp userChoice, 3

    je multiplicationOp

    cmp userChoice, 4

    je divisionOp

    jmp endProgram



additionOp:

    add ax, bx

    mov result, ax ; Store the result

    jmp displayResult



subtractionOp:

    sub ax, bx

    mov result, ax ; Store the result

    jmp displayResult



multiplicationOp:

    mul bx

    mov result, ax ; Store the result

    jmp displayResult



divisionOp:

    xor dx, dx

    div bx

    mov result, ax ; Store the result

    jmp displayResult



displayResult:

    ; Print the result message

    lea dx, resultMsg

    mov ah, 09h

    int 21h



    ; Print the actual result

    mov ax, result

    call printNumber



    ; Print a newline

    call printNewline



    ret



endProgram:

    mov ah, 4Ch

    int 21h



main endp



getch proc

    mov ah, 07h

    int 21h

    ret

getch endp



readNumber proc

    lea dx, buffer

    mov ah, 0Ah

    int 21h



    lea si, buffer + 2

    mov cx, 0



convertLoop:

    lodsb

    cmp al, 0Dh

    je endConvert

    sub al, '0'

    mov bx, 10

    mul cx

    add cx, ax

    jmp convertLoop



endConvert:

    mov ax, cx

    ret

readNumber endp



printNewline proc

    mov ah, 02h

    mov dl, 0Dh

    int 21h

    mov dl, 0Ah

    int 21h

    ret

printNewline endp



printNumber proc

    mov bx, 10

    xor cx, cx



convertLoop2:

    xor dx, dx

    div bx

    add dl, '0'

    push dx

    inc cx

    cmp ax, 0

    jne convertLoop2



printLoop:

    pop dx

    mov ah, 02h

    int 21h

    loop printLoop



    ret

printNumber endp
end main

So I'm trying to make a simple calculator where the user can choose what arithmetic operation will be used, will prompt the user to enter numbers maximum numbers of 5 twice and displays the result, but I'm having trouble with displaying the total result, after the 2nd number was inserted by the user, the "Enter 2nd Number: " will be removed and will be replaced by "The result is: 0: 21" assuming the number 21 was the inserted integer in prompt2, the code should be able to let the user choose one of the following arithmetic operator, lets the user to enter integers maximum of 5 numbers and adds or subtract it depending to what arithmetic operation the user chose and displays the result in the end


Solution

  • The first three errors

    1. Between entering the 1st and the 2nd number you issue a call printNewline, but you forget to do the same between inputting the 2nd number and displaying the result. That's why the 2nd prompt got overwritten. An interesting solution would be to include the newline codes in the result message already: resultMsg db 13, 10, 'The result is: $'

    2. If the user inputs a number that has 5 digits, you will lose the info about the operation to be performed on the numbers. The reason for this is that the buffer is 1 byte short. Correct setting: buffer db 6, ?, 6 dup(0) ; max 5 digits userChoice db ?

    3. The convertLoop is wrong in its use of mul cx. That form of the mul instruction multiplies AX by CX and leaves the product in DX:AX.
      Better keep the result that is under construction in AX and replace that lodsb (that mandatory uses AL) by other instructions that don't touch AX:

       lea  si, buffer + 2
       xor  ax, ax
      convertLoop:
       mov  cl, [si]
       inc  si
       cmp  cl, 13
       je   endConvert
       and  cx, 15       ; ['0','9'] -> [0,9]
       mov  bx, 10
       mul  bx
       add  ax, cx
       jmp convertLoop
      endConvert:
       ret