0

How can i show the 3 digit answer?

Note: I have Base 3 needed in addend and augend same as the answer need is base 3 how can i show ? I'am using notepad++ then tasm add.asm / tlink add / add. to execute the program. I'am new in dosbox so just want to learn how to show 3 digit answer in base 3.

My Code in notepad++:

.model small
.stack 100h
.data
    
    Spc     db 0dh,0ah, " $"                                                ;New Line
    ErAd31  db 0dh,0ah, "Input only number to proceed [00-22 only]. $"      ;Error Input Addition Addend and Augend
    ErAd32  db 0dh,0ah, "Input only [Y/y] Add Again [N/n] No. $"            ;Error Input Add Again
    
    ;Bases Calculation in Calculator
    BsA31   db 0dh,0ah, "   Base 03 Addition "                          ;Addition Base 03
            db 0dh,0ah, " "
            db 0dh,0ah, "Addend[00-22]:  $"
    BsA32   db 0dh,0ah, "Augend[00-22]:  $"
    
    SumA    db 0dh,0ah, "   Sum is    :  $"                             ;Sum
    AgA     db 0dh,0ah,0dh,0ah, "Add Again[Y/N]? : $"                   ;Sum Again
    
    ;Calculation Logic
    Dg11    db 0
    Dg12    db 0
    NoAd1   db 0
    NoAd2   db 0
    SumAd   db 0
    
.code
main proc
    
    mov ax,@data                    ;initialize ds
    mov ds,ax
    
    AdBs3:
        mov ah,09h
        lea dx, Spc
        int 21h
        
        lea dx, BsA31               ;Addend
        int 21h
        mov ah,01h
        int 21h                     ;1st Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg11,al
        
        mov ah,01h
        int 21h                     ;2nd Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg12,al
        
        mov al, Dg11
        mov bl,10h
        mul bl
        
        mov NoAd1,al
        mov al,Dg12
        add NoAd1,al
        jmp AdBs32
    
    ErrAd31:
        mov ah,09h
        lea dx, Spc
        int 21h
        
        lea dx, ErAd31
        int 21h
        
        jmp AdAgain
        
    Ad1:
        cmp al, 59h or 79h
        je AdBs3
        
    AdBs32:
        
        mov ah,09h
        lea dx, BsA32               ;Augend
        int 21h
        mov ah,01h
        int 21h                     ;1st Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg11,al
        
        mov ah,01h
        int 21h                     ;2nd Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg12,al
        
        mov al, Dg11
        mov bl,10h
        mul bl
        
        mov NoAd2,al
        mov al,Dg12
        add NoAd2,al
        
        ;Addition
        mov bl, NoAd1
        add bl, NoAd2
        mov cx,bx
        add cx,3210h
        
        mov ah,09h
        lea dx, SumA
        int 21h
        mov ah,02h
        mov dl,ch
        int 21h
        mov dl,cl
        int 21h
        
        jmp AdAgain
    
    AdAgain:
        mov ah,09h
        lea dx, Spc
        int 21h
        
        lea dx, AgA
        int 21h
        mov ah,01h
        int 21h
        
        cmp al, 59h or 79h
        je Ad1
        cmp al, 4Eh or 6Eh
        je AdOut
        
    AdOut:
        mov ah,4Ch                      ;end here
        int 21h
    
main endp
end main

Needed Output:

Base 03 Addition

Addend[00-22]: 22
Augend[00-22]: 22
    Sum is   :121

Add Again[Y/N]? : N
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 1
    Why are you multiplying stuff by `10h`? Anyway, you can simply implement digit-by-digit arbitrary precision addition with carry, as you learned in school. Add digits and carry from previous step. If result greater than 2, subtract 3 and produce a carry that you add to the next digit. Repeat. What problem do you have with that? PS: `cmp al, 59h or 79h` does not do what you think it does. – Jester May 27 '22 at 11:37
  • i use 10h for digits and cmp al, 59h or 79h that the user type small y or big letter Y which is same. I didn't learn it in school i just wanna try to learn. – Devil Blacklist May 27 '22 at 13:16
  • The problem is the `or` does not make a choice. I don't understand your `10h` anyway. – Jester May 27 '22 at 13:34
  • to multiply 10 to al value... – Devil Blacklist May 27 '22 at 13:47
  • 2
    Why would you multiply by 10, if it's base 3. Also, `10h` is hex, 16 decimal. – Jester May 27 '22 at 13:50
  • You probably did learn in school how to do `1234 + 5678` by hand on paper. That's what Jester is talking about. You can program the same algorithm into a computer, to handle each digit separately instead of converting into a binary integer and back. – Peter Cordes May 27 '22 at 16:17
  • my bad, i get it what you point. if i do that how do i convert the answer in base 3? – Devil Blacklist May 27 '22 at 17:03
  • How about now i edit and get the logic but the answer have 0 in last digit if small number? – Devil Blacklist May 28 '22 at 07:16
  • Your question is missing a [mcve] with actual output, and missing any debugging info. e.g. values in register that you see when single-stepping with a debugger. Also, after your last edit, there's now a `jmp Ad1`, but there's still code after it which is now unreachable. But there's no comment saying what you expect or want to happen there. – Peter Cordes May 28 '22 at 07:26
  • 1
    re: multi-digit addition: the same algorithm works identically for base 3 as it does for base 10. Computers use 8-bit bytes, so the max value is way larger than what you could get from a sum of two digits (9+9 = 18, or 19 with carry-int), and way larger than 2+2+1 = 12 in base3 = 5. So you can just add, compare and wrap, and propagate carry to the next byte. Converting to a binary integer and back is straightforward, though, and easy to adapt standard examples like Sep's answer shows. As well as being more efficient if you want to do more than a single addition. – Peter Cordes May 28 '22 at 07:29

1 Answers1

1
cmp al, 29h       <================
jle ErrAd31
cmp al, 33h
jge ErrAd31

and

mov al, Dg11
mov bl, 10h       <================
mul bl

and

mov bl, NoAd1
add bl, NoAd2
mov cx, bx
add cx, 3210h     <================

You seem to have trouble with the hexadecimal number system!

  • To check the validity of the inputted digit, you should compare with 2Fh instead of 29h. You're forgetting that hex also uses A, B, C, D, E, and F as digits. The ASCII code directly below "0" is 2Fh (because the ASCII code of "0" is 30h).

  • To convert your base-3 input, the multiplication should use 3, not 10h which is in effect equal to 16.

  • I have no idea about what you think this add cx, 3210h could be doing.


how to show 3 digit answer in base 3.

Displaying a number in base 3 is no different from displaying a number in base 10. I copied next snippet of code from my answer at Displaying numbers with DOS. I changed mov bx, 10 into mov bx, 3 et voilà...

    mov     al, NoAd1
    add     al, NoAd2
    mov     ah, 0
    ; Your number is in AX
    mov     bx, 3          ; CONST
    xor     cx, cx         ; Reset counter
.a: xor     dx, dx         ; Setup for division DX:AX / BX
    div     bx             ; -> AX is Quotient, Remainder DX=[0,2]
    push    dx             ; (1) Save remainder for now
    inc     cx             ; One more digit
    test    ax, ax         ; Is quotient zero?
    jnz     .a             ; No, use as next dividend
.b: pop     dx             ; (1)
    add     dl, "0"        ; Turn into character [0,2] -> ["0","2"]
    mov     ah, 02h        ; DOS.DisplayCharacter
    int     21h

AdAgain:

It's cumbersome how you repeat or exit the program

  mov ah,01h
  int 21h
  cmp al, 59h or 79h
  je Ad1
  cmp al, 4Eh or 6Eh
  je AdOut  
AdOut:
  • This use of or does not offer a choice between UCase and LCase.
  • Jumping to the top with a conditional jump forced you to introduce an intermediate label because the target was too far away.
  • If the user presses none of the mentioned keys, you exit the program anyway. Then why bother to compare with "N" or "n"?

Better use:

AdAgain:
    mov ah, 09h
    lea dx, Spc
    int 21h
    lea dx, AgA    ; "Continue?"
    int 21h

.z: mov ah, 01h
    int 21h
    or  al, 32     ; Make LCase
    cmp al, "n"    ; 6Eh
    je  AdOut
    cmp al, "y"    ; 79h
    jne .z         ; (*)
    jmp AdBs3      ; (**)
        
AdOut:

(*) The user must respond with "N", "n", "Y", or "y", else the question gets repeated.
(**) This jmp can jump all the way to the top. You no longer need the intermediate label Ad1.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • how do i insert this? – Devil Blacklist May 28 '22 at 04:23
  • @DevilBlacklist I made it extra easy for you to insert my code into your program because I copied these 2 lines that were already present in your program `mov al, NoAd1` `add al, NoAd2`. But I see that you have now modified your program beyond recognition! You are changing your mind too often and are forgetting that a change somewhere can have an effect at multiple other places. The answer that I wrote suits the 1st version of your question. – Sep Roland May 28 '22 at 14:49
  • @DevilBlacklist Small correction: your code was using the BL register in `mov bl, NoAd1` `add bl, NoAd2`, but no matter, that's where you need to insert my code. – Sep Roland May 28 '22 at 15:02
  • 1
    okay, I'm sorry to bother you, I'm just confused about making the logic of the dosbox. Thank you :) – Devil Blacklist May 28 '22 at 15:37