9

当我在 16 位汇编中添加两个值时,将结果打印到控制台的最佳方法是什么?

目前我有这个代码:

;;---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,打印余数(一位数),然后用商重复。

    ; 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在打印之前基本上是垃圾。

您也有大小不匹配,因为dl8 位宽和ax16 位宽。

你应该做的是翻转最后两行并修复大小不匹配:

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(十进制)之间的二进制数转换为 ascii,只需将 '0' 的 ascii 代码(即 48)添加到数字中。

于 2010-11-22T10:56:50.433 回答
2
mov dl, ax

这将不起作用dl并且ax具有不同的位大小。您要做的是创建一个循环,在其中将 16 位值除以 10,记住堆栈中的其余部分,然后使用整数除法结果继续循环。当结果为 0 时,逐位清理堆栈,将数字加 48 以将它们转换为 ASCII 数字,然后打印它们。

于 2010-11-22T10:57:26.697 回答