2

I am making a program in which I want to take two 4-digit numbers from user and display their sum.

I know how to take 4-digit input from user but I am not able to sum the 4-digit numbers and display the result.

Help required to know how I can add and display sum of two 4-digit numbers.

I am using emu8086 assembler

Here's what I have done so far. The sum is not calculated correctly. Instead of displaying a sum, some signs are displayed on the console like "$" etc.

.model small
.data  
st9 db 13,10,"Enter First Number : ",'$'
st10 db 13,10,"Enter Second Number : ",'$'
st11 db 13,10,"Result = ",'$'
num dw ?
num2 dw ? 
a dw 1000
b db 100
c db 10
.code
main proc
    mov AX,@data
    mov DS,AX

    addition:     
    mov AH,9H
    mov DX,offset st9
    INT 21H

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL a                       ;1st digit
    mov num,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL b                       ;2nd digit
    add num,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL c                      ;3rd digit
    ADD num,AX

    mov AH,1
    INT 21H                      ;4th digit
    SUB AL,30H
    ADD num,AX

    mov AH,9H
    mov DX,offset st10
    INT 21H

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL a                     ;1st digit
    mov num2,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL b                   ;2nd digit
    ADD num2,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL c                     ;3rd digit
    ADD num2,AX

    mov AH,1
    INT 21H                ;4th digit
    SUB AL,30H 
    ADD num2,AX

    call addfunc 

    exit:
    mov AH,4CH
    INT 21H 

    addfunc proc near 

        mov BX,num2
        ADD BX,num
        SUB BX,48D

        mov AH,9H
        mov DX,offset st11
        INT 21H

        mov AH,2
        mov DL,bH
        INT 21H 

        mov AH,2
        mov DL,bl
        INT 21H  

        ret 

end main
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
Yousaf
  • 27,861
  • 6
  • 44
  • 69
  • So what *do* you get? See [mcve] for how to write a more complete question. Also, what do you see when you single-step through in the debugger built-in to emu8086? – Peter Cordes Nov 29 '16 at 11:24
  • Your code doesn't have any comments, so IDK why you're subtracting `48D` from the sum, but I don't see anything that will turn an integer back into decimal digits. – Peter Cordes Nov 29 '16 at 11:25
  • @PeterCordes instead of displaying sum, some signs are displayed on the screen like $ etc. I have also edited my question. – Yousaf Nov 29 '16 at 11:27
  • That's what I expected. See my previous comment. – Peter Cordes Nov 29 '16 at 11:28
  • just a beginner in assembly language but subtracting 48D to display the correct sum on the screen. Isn't that's how sum is calculated in assembly language ? This way works when i add 2 digit numbers. – Yousaf Nov 29 '16 at 11:33
  • 1
    I haven't used emu8086, just NASM and gas. The `D` means decimal constant, right? 48 is the ASCII code for `0`. So that should work for one-digit results. (And break for everything else). I'm certain you can't turn an integer from 0-99 in BX into two ASCII digits in BL and BH with one subtraction. You need a division by 10. And of course you need to do that repeatedly when you need more than 2 digits. – Peter Cordes Nov 29 '16 at 11:45
  • 2
    Or you could just add the strings one decimal digit at a time, and handle the carry between base-10 digits yourself. – Peter Cordes Nov 29 '16 at 11:46
  • http://stackoverflow.com/a/40505938/4271923 – Ped7g Nov 29 '16 at 12:31

1 Answers1

4

Before worrying about the sum, you need to make sure that the inputs were correct. Sadly they are wrong!

When calculating the 1st digit you use mul a. Since the a variable is defined as a word (with the value of 1000), this multiplication is a word sized operation, and so it actually multiplies the AX register with your variable. Your program only gets a value in the AL register, which is but the low half of the AX register. You need to zero the upper half AH beforehand.

mov AH,1
INT 21H  
SUB AL,30H
mov ah,0          <<<<<<<<<< Add this
MUL a             ;1st digit
mov num,AX

The code for the 2nd and 3rd digits is OK, but the 4th digit is wrong again. The add num,ax instruction relies on the content of the upper half AH that you didn't set up.

mov AH,1
INT 21H           ;4th digit
SUB AL,30H
mov ah,0          <<<<<<<<<< Add this
ADD num,AX

You need these corrections on num and on num2.


addfunc proc near 
    mov BX,num2
    ADD BX,num
    SUB BX,48D

There's no sense in subtracting 48D from the sum you calculated in the addfunc procedure.
Moreover using the DisplayCharacter function from DOS on the bytes in BL and BH doesn't display the resulting number.
Below is one version of how to display a 16 bit number in AX on the screen:

addfunc proc near
 mov  ax,num2
 add  ax,num

 xor  cx,cx   ;Counts the digits
 mov  bx,10   ;Fixed divider
more:
 xor  dx,dx   ;Word division needs to zero DX!
 div  bx
 push dx      ;Remainder [0,9]
 inc  cx      ;One digit more
 test ax,ax
 jnz  more    ;Continu until AX is empty
next:
 pop  dx
 add  dl,48   ;Turn into a character, from [0,9] to ["0","9"]
 mov  ah,02h  ;DOS DisplayCharacter function
 int  21h
 loop next    ;Continu for all digits (*)

(*) Since the sum of two 4-digit numbers varies from 0 to 19998, the number of digits that are displayed varies from 1 to 5.

Fifoernik
  • 9,779
  • 1
  • 21
  • 27