2014-10-31 149 views
-2

我想將兩個預定義值一起添加並生成結果。 我的代碼現在正在做的是將16和6加在一起,這應該打印出22。然而,它打印出2 ...我真的不知道如何糾正這...添加兩個數字以生成兩位數字

這裏是代碼:

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) 

mov al, numA  ;move numA to ax 
    add al, numB  ;ax contains numa + numb 
    mov dl, al   ;move result to dl for display      

    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 

    add dl, 30h   ;Add 30h for ASCII table offset 
    mov ah, 2h   ;Store interrupt code in ah to display results in dl 
    int 21h    ;display character in dl as translated by ascii code 

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 
+0

由於你只打印1個字符,你不應該感到驚訝。要處理雙位數字,您可能需要打印十位和一位數字。根據小學數學,這將是除以10的商和餘數。 – Jester 2014-10-31 16:11:09

+0

請爲您使用的彙編程序添加標籤([tasm]或[masm]) – rkhb 2014-10-31 19:05:08

回答

0

如果你真的只想要得到一個兩位數的十進制數(如標題所暗示的),你可以使用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 

如果你也想得到一個三位十進制數字,你可以將數字隔開兩個部分。首先除以100,結果得到第一位數字。然後除以10的餘,你會得到的第二位,而第三位是餘數:

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 

如果你在前面的零干擾,可以通過反覆劃分隔離相反的順序數字10.這也是最常用的方法,如果你想轉換更大的數字:

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