Pergunta

Quando adiciono dois valores na montagem de 16 bits, qual é a melhor maneira de imprimir o resultado do console?

No momento eu tenho este código:

;;---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---;;

Eu acho que o valor de DL deve estar no código ASCII, mas não tenho certeza de como converter o valor do AX após a adição em ASCII.

Foi útil?

Solução

Você basicamente deseja dividir por 10, imprimir o restante (um dígito) e depois repetir com o quociente.

    ; 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

Como nota lateral, você tem um bug no seu código aqui:

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.

Você coloca 2 dentro ah, e então você coloca ax dentro dl. Você está basicamente, está bem ax antes de imprimi -lo.

Você também tem uma incompatibilidade de tamanho desde dl tem 8 bits de largura e ax tem 16 bits de largura.

O que você deve fazer é virar as duas últimas linhas e consertar o tamanho de incompatibilidade:

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.

Outras dicas

Basta consertar a ordem do código do @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

O algoritmo básico é:

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

Observe que isso renderá os dígitos na ordem inversa, então você provavelmente deseja substituir a etapa "emitir" por algo que armazena cada dígito, para que você possa iterar posteriormente no reverso sobre os dígitos armazenados.

Além disso, observe que, para converter um número binário entre 0 e 9 (decimal) em ASCII, basta adicionar o código ASCII para '0' (que é 48) ao número.

mov dl, ax

Isso não vai funcionar como dl e ax tem tamanhos de bits diferentes. O que você deseja fazer é criar um loop no qual você divida o valor de 16 bits por 10, lembre -se do restante na pilha e continue o loop com o resultado da divisão inteira. Quando você atingir o resultado de 0, limpe o dígito da pilha por dígito, adicionando 48 aos dígitos para transformá -los em dígitos ASCII e imprimi -los.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top