Die richtige und generische Lösung für Ihr Problem besteht darin, die Zahlen in Strings umzuwandeln. Um Ihnen zu zeigen, wie es geht ich neben Änderungen am Code vorgenommen:
- Changed die Art von
NUM
, DB
-DW
(erforderlich durch number2string
wäre es größere Zahlen halten).
- Variable
numstr
hinzugefügt, die NUM
in Zeichenfolge konvertiert wird.
- Variable
lbk
hinzugefügt (nur eine Zeilenunterbrechung nach jeder Nummer).
- hinzugefügt proc
number2string
, um eine Zahl in AX in die Zeichenfolge von SI (Dies ist die wichtigste) konvertieren konvertieren.
- hinzugefügt Proc
dollars
, um numstr
mit Dollarzeichen zu füllen (notwendig, um anzuzeigen, und die Zeichenfolge vor dem Konvertieren der nächsten Zahl löschen).
Hier ist der Code-Nummern von 0 bis 100 angezeigt wird (die Kommentare werden Ihnen helfen, es zu verstehen):
.MODEL SMALL
.STACK 100H
.DATA
NUM DW ?
lbk db 13,10,'$' ;LINE BREAK.
numstr db '$$$$$' ;STRING FOR 4 DIGITS.
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV NUM, 0 ;FIRST NUMBER.
START:
CMP NUM, 100 ;IF NUM <= 100...
JBE PRINT ;...DISPLAY NUM.
JMP END_
PRINT:
; MOV AH,2 ;THIS CODE
; MOV DL,NUM ;DISPLAYS
; INT 21H ;ONE CHAR ONLY.
;CONVERT NUMBER TO STRING.
mov si, offset numstr
mov ax, num
call number2string ;RETURNS NUMSTR.
;DISPLAY STRING.
mov ah, 9
mov dx, offset numstr
int 21h
;DISPLAY LINE BREAK.
mov ah, 9
mov dx, offset lbk
int 21h
INC NUM ;NUM++.
JMP START
END_:
MOV Ax,4C00H
int 21h
MAIN ENDP
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : AX = NUMBER TO CONVERT.
; SI = POINTING WHERE TO STORE STRING.
number2string proc
call dollars ;FILL STRING WITH $.
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov dx, 0 ;NECESSARY TO DIVIDE BY BX.
div bx ;DX:AX/10 = AX:QUOTIENT DX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp ax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
number2string endp
;------------------------------------------
;FILLS VARIABLE WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : SI = POINTING TO STRING TO FILL.
proc dollars
mov cx, 5
mov di, offset numstr
dollars_loop:
mov bl, '$'
mov [ di ], bl
inc di
loop dollars_loop
ret
endp
;------------------------------------------
END MAIN
Ab sofort kann man Zahlen number2string
und dollars
angezeigt werden können.
Mögliches Duplikat von http://stackoverflow.com/questions/15621258/assembly-printing-ascii-number – DAXaholic
Grundsätzlich müssen Sie die Binär-zu-Dezimal-Konvertierung manuell durchführen. Dies ist, was 'printf' immer hinter den Kulissen macht, aber jetzt ist es nicht da, um Ihnen zu helfen. Lesen Sie besser über 'DIV'. Erstellen Sie alternativ geschachtelte Schleifen, um die Einheiten und 10-stellige Ziffern zu drucken. –
Es wird ein ASCII-Zeichen mit dem Wert 58 (":") gedruckt. Es wird kein '10d'-Wert gedruckt, das wäre" new line feed "in ASCII. Auch die 9 bis 0 drucken nicht 0-9 Werte, sondern 48-57 Werte. Welche sind 0 bis 9 Ziffern in ASCII-Codierung. Wenn Sie also 100 zu 0 machen wollen, müssen Sie entweder einen Algorithmus erstellen, der mit 1 bis 3 ASCII-Zeichenwerten arbeitet (48-57), oder die tatsächliche Zählung in ganzzahliger Form (von 100 bis 0) durchführen und diese Zahl umrechnen in 1 bis 3 ASCII-Zeichen (48-57) nach Bedarf. Wie andere Kommentare sagen. (Ich habe das nur hinzugefügt, weil Sie "ASCII-Zeichenwert von 10d" = nein) sagen. – Ped7g