Question

Quand j'ajoute deux valeurs dans l'assemblage 16 bits, ce qui est la meilleure façon d'imprimer le résultat à la console?

En ce moment j'ai ce code:

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

Je pense que la valeur dl doit être en code ASCII, mais je ne suis pas sûr de savoir comment convertir la valeur de hache après addition en ASCII.

Était-ce utile?

La solution

Vous voulez essentiellement à diviser par 10, imprimer le reste (un chiffre), puis répéter avec le quotient.

    ; 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

Comme une note de côté, vous avez un bug dans votre code ici:

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.

Vous mettez 2 à ah, puis vous mettez ax dans dl. Vous junking essentiellement ax avant de l'imprimer.

Vous avez également une différence de taille puisque dl est de 8 bits de large et ax est large de 16 bits.

Ce que vous devez faire est de retourner les deux dernières lignes et fixer la différence de taille:

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.

Autres conseils

Juste fixant l'ordre des codes de @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

L'algorithme de base est la suivante:

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

Notez que cela donnera les chiffres dans l'ordre inverse, de sorte que vous allez probablement vouloir remplacer l'étape « emit » avec quelque chose qui stocke chaque chiffre, afin que vous puissiez plus tard itérer en sens inverse sur les chiffres enregistrés.

En outre, notez que pour convertir un nombre binaire entre 0 et 9 (décimal) à ascii, ajoutez simplement le code ascii pour « 0 » (qui est 48) au nombre.

mov dl, ax

Cela ne fonctionnera pas comme dl et ax ont des tailles différentes de bits. Ce que vous voulez faire est de créer une boucle dans laquelle on divise la valeur 16 bits 10, rappelez-vous le reste sur la pile, puis continuer la boucle avec le résultat de la division entière. Lorsque vous atteignez un résultat de 0, nettoyer le chiffre de la pile par chiffre, en ajoutant 48 aux chiffres pour les transformer en chiffres ASCII, puis les imprimer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top