2010-11-22 9 views
6

Wenn ich zwei Werte in 16-Bit-Assembly hinzufügen, was ist der beste Weg, um das Ergebnis auf Konsole zu drucken?Drucken Integer zu Konsole in x86-Assembly

Im Moment habe ich diesen 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---;; 

Ich denke, dass dl Wert im ASCII-Code sein sollte, aber ich bin nicht sicher, wie Axt Wert nach der Zugabe in ASCII zu konvertieren.

Antwort

10

Sie möchten grundsätzlich durch 10 dividieren, den Rest (eine Ziffer) drucken und dann mit dem Quotienten wiederholen.

; 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 

Als Randbemerkung, haben Sie einen Fehler im Code hier:

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. 

Sie 2 in ah setzen, und dann setzen Sie ax in dl. Sie sind im Grunde Junking ax vor dem Drucken.

Sie haben auch eine Größenabweichung, da dl 8 Bit breit ist und ax 16 Bit breit ist.

Was sollten Sie tun, ist es, die letzten beiden Zeilen drehen und die Größe Mismatch beheben:

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

Der grundlegende Algorithmus ist:

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

Beachten Sie, dass dies die Ziffern in der umgekehrten Reihenfolge ergeben wird, so sind Sie wahrscheinlich mit etwas der „emit“ Schritt ersetzen, gehen zu wollen, dass jede Ziffer speichert, so dass Sie später rückwärts über die gespeicherten Ziffern iterieren können.

Beachten Sie außerdem, dass zum Konvertieren einer Binärzahl zwischen 0 und 9 (dezimal) in ascii nur der ASCII-Code für '0' (48) zur Zahl hinzugefügt werden muss.

1
mov dl, ax 

Das wird nicht funktionieren, wie dl und ax unterschiedliche Bit-Größen haben. Sie möchten eine Schleife erstellen, in der Sie den 16-Bit-Wert durch 10 teilen, den Rest auf dem Stapel merken und dann die Schleife mit dem Ganzzahl-Divisionsergebnis fortsetzen. Wenn Sie das Ergebnis 0 erreicht haben, bereinigen Sie den Stapel Ziffer für Ziffer, fügen Sie den Ziffern 48 hinzu, um sie in ASCII-Ziffern umzuwandeln, und drucken Sie sie dann aus.

4

Nur die Reihenfolge der @Nathan Fellman Festsetzung ‚s Code

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