Adding two numbers to make a two digit number

前端 未结 1 889
渐次进展
渐次进展 2021-01-29 11:51

I want to add two predetermined values together and produce the result. What my code is doing at the moment is it is adding 16 and 6 together which should print out 22. However

相关标签:
1条回答
  • 2021-01-29 12:17

    If you really only want to get a two-digit-decimal-number (as the title suggests), you can use AAM:

    data    segment                         ; data segment. Keyword db means define byte. You can also define word (dw)
            numA    db  16                  ;Define first variable
            numB    db  06                  ;Define second variable
            StrMsg  db 'The answer is $'    ;return message to the user
            leng    db 1                    ;length of the charachters - this value will be overwritten
    data    ends
    
                                            ; stack segment
    stack1  segment stack
            db  100 dup(?)                  ; This is the stack of 100 bytes
    stack1  ends
    
    
    code    segment
            assume  cs:code, ds:data, ss:stack1
    
    start:
                            ;Perform initialization
        mov ax, data        ;Put the starting address of the data segment into the ax register (must do this first)
        mov ds, ax          ;Put the starting address of the data segment into the ds register (where it belongs)
    
        mov ax, stack1      ;Put the starting address of the stack into the ax register (must do this first)
        mov ss, ax          ;Put the starting address of the stack segment into the ss register (where it belongs)
    
        lea dx, StrMsg      ;load message to display the result to the user
        mov ah, 9h          ;display string subroutine
        int 21h             ;interrupt for MS-DOS routine
    
        mov al, numA        ;move numA to al
        add al, numB        ;al contains numa + numb
    
        lea di, StrMsg      ; Place for target string (The old value of StrMsg isn't used anymore)
        aam                 ; AL => AH (first dec. digit) AL (second dec. digit) (unpacked BCD)
        or ax, 3030h                 ; Convert both digits to ASCII
        mov BYTE PTR [di], ah        ; Store first digit
        mov BYTE PTR [di+1], al      ; Store second digit
        mov BYTE PTR [di+2], '$'     ; Store termination character for 'int 21h fn 09h'
    
        lea dx, StrMsg      ;load message to display the result to the user
        mov ah, 9h          ;display string subroutine
        int 21h             ;interrupt for MS-DOS routine
    
        mov ah, 4ch         ;Set up code to specify return to dos
        int 21h             ;Interpt number 21 (Return control to dos prompt)
    
    code    ends
    
    end     start
    

    If you also want to get a three-digit-decimal-number, you can isolate the digits by two divisions. First divide by 100 and you get the first digit as result. Then divide the remainder by 10 and you get the second digit while the third digit is in the remainder:

    data    segment                         ; data segment. Keyword db means define byte. You can also define word (dw)
            numA    db  16                  ;Define first variable
            numB    db  06                  ;Define second variable
            StrMsg  db 'The answer is $'    ;return message to the user
            leng    db 1                    ;length of the charachters - this value will be overwritten
    data    ends
    
                                            ; stack segment
    stack1  segment stack
            db  100 dup(?)                  ; This is the stack of 100 bytes
    stack1  ends
    
    
    code    segment
            assume  cs:code, ds:data, ss:stack1
    
    start:
                            ;Perform initialization
        mov ax, data        ;Put the starting address of the data segment into the ax register (must do this first)
        mov ds, ax          ;Put the starting address of the data segment into the ds register (where it belongs)
    
        mov ax, stack1      ;Put the starting address of the stack into the ax register (must do this first)
        mov ss, ax          ;Put the starting address of the stack segment into the ss register (where it belongs)
    
        lea dx, StrMsg      ;load message to display the result to the user
        mov ah, 9h          ;display string subroutine
        int 21h             ;interrupt for MS-DOS routine
    
        mov al, numA        ;move numA to ax
        add al, numB        ;ax contains numa + numb
        mov dl, al          ;move result to dl for display
    
        lea di, StrMsg      ; Place for target string (The old value of StrMsg isn't used anymore)
        call al2dec
    
        lea dx, StrMsg      ;load message to display the result to the user
        mov ah, 9h          ;display string subroutine
        int 21h             ;interrupt for MS-DOS routine
    
        mov ah, 4ch         ;Set up code to specify return to dos
        int 21h             ;Interpt number 21 (Return control to dos prompt)
    
    al2dec PROC             ; Args: AL register to convert, DS:DI pointer to target string
        mov bl, 100
        xor ah, ah          ; Clear AH for division
        div bl              ; AL = AX / BL remainder AH
        or al, 30h          ; Convert result to ASCII
        mov BYTE PTR [di], al        ; Store as first digit
    
        shr ax, 8           ; Shift remainder into AL, clear AH
        mov bl, 10
        div bl              ; AL = AX / BL remainder AH
        or al, 30h          ; Convert result to ASCII
        mov BYTE PTR [di+1], al      ; Store as second digit
    
        or ah, 30h          ; Convert remainder to ASCII
        mov BYTE PTR [di+2], ah      ; Store as third digit
    
        mov BYTE PTR [di+3], '$'     ; Store at last termination character for 'int 21h fn 09h'
        ret
    al2dec ENDP             ; DS:DI contains string with decimal digits
    
    code    ends
    
    end     start
    

    If you're disturbed by the leading zeroes, you can isolate the digits in reversed order by repeatedly dividing by 10. This is also the most used method, if you want to convert bigger numbers:

    al2dec PROC                         ; Args: AL register to convert, DS:DI pointer to target string
        mov bl, 10                      ; Base 10 -> divisor
        xor cx, cx                      ; CX=0 (number of digits)
    
      al2dec_loop_1:                    ; 1st loop
        xor ah, ah                      ; Clear AH for division (don't forget it!)
        div bl                          ; AL = AX / BL   Remainder AH
        push ax                         ; Push remainder for LIFO in Loop_2
        add cl, 1                       ; Equivalent to 'inc cl'
        test al, al                     ; AL = 0?
        jnz al2dec_loop_1               ; No: once more
      al2dec_loop_2:                    ; 2nd loop
        pop ax                          ; Get back pushed digits
        or ah, 00110000b                ; Conversion to ASCII
        mov BYTE PTR [di], ah                    ; Store only AH to [DS:DI] (DI is a pointer to a string)
        add di, 1
        loop al2dec_loop_2              ; Until there are no digits left
    
        mov BYTE PTR [di], '$'                   ; Store termination character for 'int 21h fn 09h'
        ret                             ; Ret: DS:DI contains decimal '$'-terminated ASCII-String
    al2dec ENDP
    
    0 讨论(0)
提交回复
热议问题