5

I managed to make the addition of two-digit numbers based on the solutions provided by helpful people from the thread I created last time:

How do I use ADC in assembly?

So now, there seems to be a problem when I add 2 numbers and their result will be a 3-digit number. The jump named IS_3DIGIT handles that possibility, but addition of some numbers like 80 + 80, 99 + 99, 89 + 82 all give wrong results. 56 + 77 works well. So my hypothesis is that adding two numbers higher than 79 will give wrong results. How can I resolve this problem? BTW, additions like 99 + 23 or 89 + 43 give correct results.

.MODEL SMALL
.STACK 1000
.DATA

MSGA DB 13,10,"Input first number: ","$"
MSGB DB 13,10,"Input second number:","$"
MSGC DB 13,10,"The sum is: ","$"

NUM1 db ?
NUM2 db ?
NUM3 db ?

.CODE

MAIN PROC NEAR

MOV AX, @DATA
MOV DS, AX

; get first number
LEA DX, MSGA
MOV AH, 09h
INT 21h

MOV AH, 01
INT 21H
SUB AL, '0'

MOV BL, AL

MOV AH, 01
INT 21H
SUB AL, '0'

MOV CL, AL

; get second number
LEA DX, MSGB
MOV AH, 09h
INT 21h

MOV AH, 01
INT 21H
SUB AL, '0'

MOV DL, AL

MOV AH, 01
INT 21H
SUB AL, '0'

MOV DH, AL

; add
MOV AL, CL
MOV AH, BL
ADD AL, DH
AAA 
ADD AH, DL

MOV NUM1, AL
ADD NUM1, '0'

; if tens digit is less than or equal to 9
CMP AH, 9
JLE NOT_3DIGIT 

IS_3DIGIT:
MOV AL, AH   ; move value of ah to al
SUB AH, AH   ; clear ah
ADD AL, 0    ; al + 0 = al (tens digit)
AAA          ; move for addition
ADD AH, 0    ; ah + 0 + 1 = ah + 1 (hundreds digit)
MOV NUM2, AL
MOV NUM3, AH
ADD NUM2, '0'
ADD NUM3, '0'
; output sum
LEA DX, MSGC
MOV AH, 09h
INT 21h
MOV DL, NUM3
MOV AH, 02H
INT 21h
MOV DL, NUM2
MOV AH, 02H
INT 21h
JMP PRINT_LASTDIGIT


NOT_3DIGIT:    
MOV NUM2, AH
ADD NUM2, '0'
; output sum
LEA DX, MSGC
MOV AH, 09h
INT 21h
MOV DL, NUM2
MOV AH, 02H
INT 21h

PRINT_LASTDIGIT:
MOV DL, NUM1
MOV AH, 02H
INT 21h

EXIT:
MOV AH, 4Ch
INT 21h

MAIN ENDP
END MAIN
Community
  • 1
  • 1

2 Answers2

1

Well you did it the "hard way", really. Again, aaa can do all the hard work, as long as the right things are in ah and al, so different cases for overflow and no overflow aren't really necessary.

Something like this (untested):

; ah:al = tens:ones
add al,dh
aaa
; now make ah:al hundres:tens
mov bl,al
mov al,ah
xor ah,ah   ; this will be the hundreds digit
add al,dl
aaa
; result in ah:al:bl

I took the use of dh and dl from your source, and bl is just some extra place. They're not important, but the things in ah and al really have to be there, just as last time.

I've read the descriptions of aaa and add very closely, and I think that should work even though the second add can be adding 10 to something, but I'm only about 90% sure about that.

harold
  • 61,398
  • 6
  • 86
  • 164
  • Now I finally get it. I didn't know about xor. I have a lot more to study. Thanks for your help. – six.strings.and.a.bit Jul 20 '12 at 09:47
  • You're welcome, @jrmeasures. The `xor` isn't really crucial there - it's just there to set `ah` to zero, much like you did with `sub`. – harold Jul 20 '12 at 09:57
  • what about the AAD for DIV? From what I know, AL register is used for the quotient and AH will be used for the remainder. How shall I use AAD? – six.strings.and.a.bit Jul 20 '12 at 10:21
  • 1
    @jrmeasures it just does `ax = (al + 10 * ah) & 0xFF`, basically. If `ah:al` was a pair of decimal digits, `ax` will hold the binary representation of it after `aad`. `aam` does the reverse - it unpacks `al` to two decimal digits (or it tries to, at least. Obviously things go wrong after 99). That's really material for a different question I'd say, a general one about decimal math maybe? – harold Jul 20 '12 at 10:34
  • All this info would be great if i wantto control BCD-leds from my computer. or if i want custom_printf – huseyin tugrul buyukisik Jul 20 '12 at 14:02
0

I think it can be done in other way round. There is no need to check whether it has become 3 digit or not.

PRINT MACRO MSG
      LEA DX,MSG
      MOV AH,09H
      INT 21H
ENDM     

READ MACRO N,J1,J2
      J1: MOV AH,01H
          INT 21H
      CMP AL,0DH
      JE J2
      SUB AL,30H
      MOV BL,AL
      MOV AX,N
      MOV DX,0AH
      MUL DX
      XOR BH,BH
      ADD AX,BX
      MOV N,AX
      JMP J1
  J2: NOP
ENDM     

PRINTMUL MACRO N1,L2,L3
            MOV BX,000AH
            MOV AX,N1
            XOR CX,CX 

       L2: XOR DX,DX
           DIV BX
           PUSH DX
           INC CX
           CMP AX,0000H
           JNE L2      

       L3: POP DX
           ADD DL,30H
           MOV AH,02H
           INT 21H
           LOOP L3
ENDM  

.MODEL SMALL
.STACK 100H
.DATA
    N DW 0
    M DW 0  
    MS DB 0DH,0AH,"ENTER 1ST: $"    
    MT DB 0DH,0AH,"ENTER 2ND: $"
    ANS DB 0DH,0AH,"ANSWER IS: $"
.CODE
MAIN PROC 
    MOV AX,@DATA
    MOV DS,AX

    PRINT MS
    READ N,U1,U2

    PRINT MT
    READ M,G1,G2 

    PRINT ANS 
    MOV AX,N       
    ADD AX,M 

    PRINTMUL AX,H1,J5

MAIN ENDP
END MAIN
Paul Roub
  • 36,322
  • 27
  • 84
  • 93