9

16 ビット アセンブリで 2 つの値を追加するとき、結果をコンソールに出力する最良の方法は何ですか?

現時点では、次のコードがあります。

;;---CODE START---;;
mov ax, 1   ;put 1 into ax
add ax, 2   ; add 2 to ax current value
mov ah,2  ; 2 is the function number of output char in the DOS Services.
mov dl, ax ; DL takes the value.
int 21h    ; calls DOS Services

mov ah,4Ch   ; 4Ch is the function number for exit program in DOS Services.
int 21h      ; function 4Ch doesn't care about anything in the registers.
;;---CODE END---;;

dl の値は ASCII コードにすべきだと思いますが、加算後の ax の値を ASCII に変換する方法がわかりません。

4

4 に答える 4

12

基本的には、10 で割って余り (1 桁) を出力し、その商を繰り返します。

    ; assume number is in eax
    mov ecx, 10

loophere:
    mov edx, 0
    div ecx

    ; now eax <-- eax/10
    ;     edx <-- eax % 10

    ; print edx
    ; this is one digit, which we have to convert to ASCII
    ; the print routine uses edx and eax, so let's push eax
    ; onto the stack. we clear edx at the beginning of the
    ; loop anyway, so we don't care if we much around with it

    push eax

    ; convert dl to ascii
    add dl, '0'

    mov ah,2  ; 2 is the function number of output char in the DOS Services.
    int 21h    ; calls DOS Services

    ; now restore eax
    pop eax

    ; if eax is zero, we can quit

    cmp eax, 0
    jnz loophere

補足として、ここのコードにバグがあります。

mov ax, 1   ;put 1 into ax
add ax, 2   ; add 2 to ax current value
mov ah,2  ; 2 is the function number of output char in the DOS Services.
mov dl, ax ; DL takes the value.

を入れ2ah次に を入れaxますdl。あなたは基本的axにそれを印刷する前にジャンクしています。

dlは 8 ビット幅でax16 ビット幅であるため、サイズの不一致もあります。

すべきことは、最後の 2 行を反転して、サイズの不一致を修正することです。

mov ax, 1   ;put 1 into ax
add ax, 2   ; add 2 to ax current value

mov dl, al ; DL takes the value.
mov ah,2  ; 2 is the function number of output char in the DOS Services.
于 2010-11-22T13:09:36.923 に答える
7

@Nathan Fellman のコードの順序を修正するだけです

PrintNumber proc
    mov cx, 0
    mov bx, 10
@@loophere:
    mov dx, 0
    div bx                          ;divide by ten

    ; now ax <-- ax/10
    ;     dx <-- ax % 10

    ; print dx
    ; this is one digit, which we have to convert to ASCII
    ; the print routine uses dx and ax, so let's push ax
    ; onto the stack. we clear dx at the beginning of the
    ; loop anyway, so we don't care if we much around with it

    push ax
    add dl, '0'                     ;convert dl to ascii

    pop ax                          ;restore ax
    push dx                         ;digits are in reversed order, must use stack
    inc cx                          ;remember how many digits we pushed to stack
    cmp ax, 0                       ;if ax is zero, we can quit
jnz @@loophere

    ;cx is already set
    mov ah, 2                       ;2 is the function number of output char in the DOS Services.
@@loophere2:
    pop dx                          ;restore digits from last to first
    int 21h                         ;calls DOS Services
    loop @@loophere2

    ret
PrintNumber endp
于 2011-04-27T23:57:54.857 に答える
4

基本的なアルゴリズムは次のとおりです。

divide number x by 10, giving quotient q and remainder r
emit r
if q is not zero, set x = q and repeat 

これは逆の順序で数字を生成することに注意してください。そのため、保存された数字を後で逆に反復できるように、「放出」ステップを各数字を保存するものに置き換えたいと思うでしょう。

また、0 から 9 (10 進数) までの 2 進数を ascii に変換するには、'0' の ascii コード (48) を数値に追加するだけです。

于 2010-11-22T10:56:50.433 に答える
2
mov dl, ax

これは動作せずdlaxビット サイズが異なります。やりたいことは、16 ビット値を 10 で割るループを作成し、残りをスタックに記憶してから、整数除算の結果でループを続けることです。結果が 0 になったら、スタックの桁を 1 桁ずつクリーンアップし、桁に 48 を追加して ASCII 桁に変換し、出力します。

于 2010-11-22T10:57:26.697 に答える