2010-11-22 19 views
6

Lorsque j'ajoute deux valeurs dans l'assemblage 16 bits, quel est le meilleur moyen d'imprimer le résultat sur la console?Imprimer l'entier de la console dans l'assemblage x86

Au moment où 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.

Répondre

10

Vous souhaitez fondamentalement 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 mis 2 à ah, puis vous mettez ax dans dl. Vous êtes essentiellement junking ax avant de l'imprimer.

Vous avez également une différence de taille car dl a une largeur de 8 bits et ax une largeur 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. 
4

L'algorithme de base est:

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, vous allez probablement vouloir remplacer l'étape « émettre » avec quelque chose qui stocke chaque chiffre, de sorte que vous pouvez ensuite inverser en sens inverse sur les chiffres enregistrés.

Notez également que pour convertir un nombre binaire compris entre 0 et 9 (décimal) en ascii, ajoutez simplement le code ascii de '0' (48) au nombre.

1
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 vous divisez la valeur de 16 bits par 10, souvenez-vous du reste sur la pile, puis continuez la boucle avec le résultat de la division entière. Lorsque vous atteignez un résultat de 0, nettoyez le pavé numérique par chiffre, en ajoutant 48 aux chiffres pour les convertir en chiffres ASCII, puis imprimez-les.

4

Juste fixer l'ordre du Code 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